help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Current working directory echoed to the terminal


From: Bob Proulx
Subject: Re: [Help-bash] Current working directory echoed to the terminal
Date: Sun, 15 Apr 2012 18:15:12 -0600
User-agent: Mutt/1.5.21 (2010-09-15)

Chris Jones wrote:
> Bob Proulx wrote:
> > Okay.  So you want shell aliases to be available to "scripts".  I use
> > "scripts" here because I am not sure how vim invokes :! commands.  I
> > imagine it is using something similar to '$SHELL -c "cmd"' there when
> > there are shell metacharacters present and testing seems to confirm this.
> 
> It's not even that technical:
> 
> I just want to be able to issue single ‘shell commands’ from Vim as if
> I was at the bash prompt. This means everything that's available at the
> shell prompt, including aliases and functions. 

I think we just said the same thing.  ;-)

Running a command from emacs/vi/vim or other program would be called a
shell escape.  You are escaping out of the program and running a shell
command.  That shell command is desired to be a shell alias at this
moment but is more typically a shell script or external program or
whatever.  That difference between is getting to be infinitesimally
small and not worth discussing.  However aliases are usually not
available there.  At least not without special configuration.

> > The part I don't like about setting BASH_ENV is that it forces an
> > overhead upon every script.  It can be a noticeable slowdown if every
> > script must source the environment file.  (Of course if you haven't
> > noticed then you would argue that it wasn't noticeable.)
> 
> It's not so much the overhead, which in my case is negligible.

Acknowledged.  But it isn't always negligible.  I have had cases where
the overhead was quite large when always sourcing the environment
script and special effort was needed to keep things trim so that
performance was reasonable.

> The part I don't like is that it's just not right to systematically
> source bash aliases and functions where you don't need them. For all
> I know, there could even be corner cases where this might lead to
> hard-to-track-down bugs.

Exactly!  I related one such case with the 'if' alias.  (I still
chuckle about that one from time to time.  But I am easily amused.)


> I think that aliases are fine in interactive shells as long as you use
> them in moderation.

"Eggsellent"[sic].  All things in moderation.  Including moderation.
Which means you must take something to excess sometimes.

> > For example for your alias example above 'l | b' I would have created
> > two shell scripts named 'l' and 'b' that implemented that behavior.
> > It would have been exactly the same for your muscle memory.  But it
> > would not have required BASH_ENV to load the aliases.
> 
> Ah.. But scripts add the overhead of creating extra processes while
> aliases are only a syntax substitution hack that remains local to the
> parent shell.

Yes.  But that process was already in memmory.  That makes it very
light weight to start another instance of it.

And while your alias is very efficient for command line use it becomes
much less so when you force every later shell script to source your
~/.bashrc and parse it for every command.  A lot of commands in
/usr/bin/ will be shell scripts.  Some will be #!/bin/bash and those
will be forced to read BASH_ENV if set.

So while aliases for your command shell are going to be very efficient
setting BASH_ENV causes a performance penalty in other places.  I
don't think the two balance out.  Of course I will defer to any hard
objective performance data but without doing that I think it will be a
net loss in my typical usage.

> > Note that patch for sshd and bash above?  Same thing.  When running a
> > remote command over ssh onto a remote host it won't be an interactive
> > shell and won't have loaded any aliases.  If the commands were scripts
> > then the behavior would work without problem remotely.  But if trying
> > to use shell aliases over a remote shell then special configuration is
> > needed to cause them to be loaded and available.
> 
> That's not alias-specific: it would happen anyway because my custom bash
> functions or even scripts (not to mention my Vim rcfile) are not going
> to be available on all remote systems either unless I do some special
> configuration.

On Debian that special configuration has already been done for you.
So actually your custom aliases and custom functions *are* available
to you unless you specifically disable it!

This feature has been somewhat controverial.  Some love it and some
hate it.  Your .bashrc file may be customized so on a Debian system I
would look in /etc/skel/.bashrc for the default user template of the
file and see this construct or a similar one there.  There are
variations on this theme so you might see something different but
similar in intent.

  [ -z "$PS1" ] && return

Any code above it is read and executed by a remote shell command
through ssh while any code after it is not.  If you wished aliases to
be available to your shell then you would put those lines above the
return statement line.  If not then that would go below.  By putting
your alias above that line you would then have them available over a
remote ssh invoked shell.

  $ ssh foo.example.com myalias

However because that feature is an optionally enabled feature / patch
to the shell if you use different systems you would find it enabled on
some and not enabled on others.  Therefore while it is useful it is
also somewhat pernicious too.  Again, real shell scripts are probably
better and it avoids the issue.

> > I am not a vim person but if I were, and I were embracing aliases, I
> > would try to limit the scope of BASH_ENV by only setting it from
> > within vim.  
> 
> I've come to the conclusion that Vim doesn't handle temporarily escaping
> to a shell as gracefully as it should, but I'm not sure there's anything
> I can do about it.

As far as I can tell vim is reasonable about how it does this.  What
would you have it do differently?  And I will keep reading as you tell
me just that. :-)

> Here is the dilemma:
> 
> By default, Vim's shell escape mechanism causes a non-interactive shell
> to be launched, which proceeds to run the command that the user entered
> at the Vim command line. Since the shell is not an interactive shell, no
> bashrc user-controlled customization of the environment takes place and
> bash aliases and functions are not available.

Seems reasonable to me.

> As far as I can tell, there are two ways you can work around this:
> 
> 1. Customize Vim to force the escape shell to be interactive: this
>    causes the  ~/.bashrc file to be sourced and aliases & functions
>    become available.

You could easily do this yourself.  Set 'SHELL="bash -i"' in your vim
environment.  Then when it calls $SHELL -c "cmd" it would expand and
call it as bash -i -c "cmd" and the shell would be interactive and
would source your .bashrc file.

Of course having SHELL be a string with spaces requiring a shell to
parse is not general.  But it seems to work for vim okay.

> 2. Customize bash via the BASH_ENV variable to force the sourcing of
>    aliases & functions for all non-interactive shells including scripts
>    run outside the Vim context.

And that has that performance penalty that I didn't like, and the
potental to break scripts by using conflicting aliases and customized
behavior.  A common thing (that I don't prefer but some do) is to
alias rm to 'rm -i'.  That would break a lot of scripts for example.

> The nice thing about the first solution is that it is local to Vim but
> it has one annoying drawback¹: for reasons I do not fully understand,
> control is never returned to Vim.. I either have to manually issue an
> 'fg' or an 'exit' to wake up my Vim session.

I noticed that too.  I don't know why.  Perhaps someone else will know.

> This can get nasty when Vim is invoked by another program such as
> mutt: I issued a ‘wc’ command to check the size of my vimrc.. and I
> was unable to get control back. So, I had to kill my mutt/Vim
> session & re-type the better part of this message. :-(

The autorecovery from swap file didn't work?  'vim -r'?

> As to the second solution, I realize it is not really satisfactory but
> at least it does the job, so it looks like I'll have to stick with it
> for the time being..

Understanding the issues is the most important part.

> I could report this issue to the Vim user list, but I have a feeling
> that s/o will tell me that a simple workaround is to convert my aliases
> & functions to scripts.. :-)  

:-)

> > I think Greg's suggested improvement to your environment script to
> > avoid the cd calls entirely was a really good improvement.  
> 
> His ‘improvement’ left me rather speechless, I must say.. and a little
> pissed at not having found the solution myself..

We all miss things.  Being part of a good team is almost always more
enjoyable than going completely solo.  People help each other out.

> ¹ Incidentally there is another aspect, especially on debian: when the
>   shell is interactive, there is a noticeable slowdown due to all the
>   debian-specific function code that gets sourced:

Debian specific?  Debian has almost no system specific code.  If you
compare it to other systems I think you will find that most other
systems have a significantly larger amount of system specific shell
startup code.  All you will really find on Debian is bash_completion
being loaded.  On other systems look at 'ls /etc/profile.d/*.sh' and
see quite a bit more.

>   I issued a ‘:! set | wc’ after changing the Vim ‘shell’ option to
>   ‘/bin/bash -i’ and the output was almost 10,000 lines..!

The bash_completion adds up to a lot of code.

>   Not much of a problem in normal circumstances where you start an
>   interactive shell and proceed to issue hundreds of commands, but
>   here all this sourcing happens every time you run a command from
>   Vim... On underpowered hardware, this could be annoying..

You could avoid loading bash_completion, perhaps uninstalling it.  But
it is very useful and addicting to have available.

Bob



reply via email to

[Prev in Thread] Current Thread [Next in Thread]