This site is now 100% read-only, and retired.

Question: Share your bash tips?

Posted by Steve on Fri 29 Apr 2005 at 02:27

GNU Bash is one of the most common shells in the Linux world, it's also the default shell on Debian systems. People who use it frequently and browse the manual usually learn something new, here I'm going to share two tips I cannot live without. What are yours?

Autocompletion

autocompletion is literally what it's name might suggest, you start to type something and it's completed for you.

This is usually enabled for simple things such as file and directory names, and by default it will be activated by the "TAB" key.

For example if you wish to look at the system's password file you might wish to run:

less /etc/passwd

To save keystrokes you can actually type:

lesTAB /eTAB/passTAB

As you proceed to type the words pressing TAB will automatically complete things for you.

In the Debian bash package there is a file installed called /etc/bash_completion, this adds a lot more useful behaviours to bash including:

  • Auto completion of hostnames, for SSH
  • Auto completion of Debian specific utilities

To cause your shell to use it run the following command, then login again:

echo '. /etc/bash_completion' >> ~/.bashrc

This will now give you a lot more completions, most usefully I find the following :

apt-get upgTAB

This becomes the familiar "apt-get upgrade", other apt-get, and dpkg commands suddenly understand completion too, so instead of typing "dpkg --search" you can cut this down to "dpkg --seaTAB".

To be honest I don't know the full extent of the completion offered as some of the code in the /etc/bash_completion file is pretty hard to follow, but I know it saves me time.

Why not have a look yourself?

Switching to the previous directory

Assuming that you work in the shell for moving around, and working on files then it's often common to switch directories a lot.

One thing that I often find I want to do is move to a long directory path, do something, then go elsewhere. Frequently I wish to go back to the long directory and do something else i've forgotten.

Even with directory completion it's often a pain to have to retype out the previous directory.

Consider the following example:

cd /home/www/www.debian-administration.org/htdocs/
# do something

cd /home/www/www.steve.org.uk/htdocs
# do something else

cd /home/www/www.debian-administration.org/htdocs/
# Ooops forgot something.

Here we want to move back to a directory we just left, and rather than typing out the full path we can take advantage of the fact that bash remembers our previous directory and sets up an alias for it: -.

To change to the previous directory just run:

cd -

Here's an example showing it in use:

# Change to a long directory.
steve@skx:~$ cd /home/www/www.debian-administration.org/htdocs
steve@skx:/home/www/www.debian-administration.org/htdocs$ 

#
# Do something ..
#

# Go to /tmp
steve@skx:/home/www/www.debian-administration.org/htdocs$ cd /tmp

#
# Realise we wanna go back
#
steve@skx:/tmp$ cd -
/home/www/www.debian-administration.org/htdocs

Other solutions to this problem exist, including pushd, and popd, but I admit I find the simplicity of the "cd -" command much more useful.

Argument Reuse

If you're used to running commands from the shell a lot one thing that's incredibly useful is the ability to reuse argumetns from previous commands.

Say you wished to run the following commands:

cp /etc/passwd my-password-copy
emacs my-password-copy

Here we copy a file somewhere, then attempt to edit it.

Instead of typing out the filename we can take advantage of another of bash's shortcuts - it remembers the last argument to the previous command, and allows you to insert it into the current shell with "Esc .".

Run the following to see how it works:

cat /etc/passwd
cp ESC. .

(That is press Esc, then press '.' afterwards' - the last argument to the previous command is inserted into the command line).

Your tips

What features of the bash shell do you find the most useful? Do you have any interesting tips to share?

 

 


Re: Question: Share your bash tips?
Posted by Anonymous (216.86.xx.xx) on Fri 29 Apr 2005 at 05:23
my favorite obscure bash trick is control-r.

On a blank command line, hit control-r to do a "reverse incremental search". As you type, bash will search your command history and auto-fill the most recent command that matches the pattern you type in. Hit control-r again to go back to the next most recent match. I use this one all the time. :)

--Nato

[ Parent ]

Re: Question: Share your bash tips?
Posted by agi (82.159.xx.xx) on Fri 29 Apr 2005 at 12:03
I'm a great fan of Ctrl+R, and thus use it a lot, and very fast. This usually means that I run past what I was looking for. Instead of hitting Ctrl+C and start searching again, you can use Ctrl+S (twice) to search backwards.

[ Parent ]

Re: Question: Share your bash tips?
Posted by jaddle (66.11.xx.xx) on Fri 29 Apr 2005 at 20:23
Hmm, for me, ctrl-s just freezes the terminal (in any terminal I've tried) and requires a ctrl-q to unlock it. Doesn't seem to do anything for bash....

[ Parent ]

Re: Question: Share your bash tips?
Posted by agi (82.159.xx.xx) on Sat 30 Apr 2005 at 09:49
It doesn't happen to me, but you are right. I remember experiencing that behavior sometimes in the past. I don't know what will trigger one thing or the other, but it's working for me in all my terminals right now. From the man page
reverse-search-history (C-r) Search backward starting at the current line and moving ‘up’ through the history as necessary. This is an incremental search. forward-search-history (C-s) Search forward starting at the current line and moving ‘down’ through the history as necessary. This is an incremental search.

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (67.10.xx.xx) on Sun 1 May 2005 at 13:10
This is true (the ^s does searching) but in a terminal emulator most generally they override that and use it as "stop" or "pause", requiring one to press ^q to "unpause" it...

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (69.157.xx.xx) on Mon 2 May 2005 at 15:43
Indeed.
If you press ^s while in a screen session, your session will 'freeze'.

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (67.81.xx.xx) on Tue 3 May 2005 at 21:17
# disable XON/XOFF flow control (^s/^q)
stty -ixon

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (81.197.xx.xx) on Sun 8 May 2005 at 16:29
It's due to terminal settings. You need to move the C-s key away. See this listing
  $ stty -a
And put these lines to your ~/.profile
  stty stop  '^-'

stty start '^-'
Those are not "Control", but char (^) followed by char(-). They disable those terminal settings.

Jari Aalto

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (65.7.xx.xx) on Wed 22 Feb 2006 at 17:27
If you press Ctrl-S, and then type something cool like 'Bash is Born Again', and then press Scroll Lock, you should see it output at the command line. At least that's the way it works for me.

Works as a nice honeypot too, if you have the time to discreetly disable your Scroll Lock key. ;)

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (207.171.xx.xx) on Wed 28 Feb 2007 at 21:17
He said ctrl+S (capital) -- did you try that? Just wondering. I haven't yet.

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (138.4.xx.xx) on Fri 29 Apr 2005 at 07:47
I find very useful simple aliases inserted in .profile, .bashrc or wathever be the file you use to adapt your environment.

They are mainly to find things into long outputs from certain commands.

My conventions is repeating the last letter of the long output command. The examples will clarify things inmediatly
-To see something coming into ls output: lss
alias lss='ls -lrt | grep $1'

-To check a process is running in a box with a heavy load: pss
alias pss='ps -ef | grep $1'

-To check the existence of an environment variable: envv
alias envv='env | grep $1'

-To see if a package or packages are installed in the system: dpkgg
alias dpkgg='dpkg -l | grep $1'

etc.

This may admit lots of modifications to make these aliases fit better your needs, like, including more arguments ( $2, $3, etc), or piping more commands to suit some long operation that one perform frequently, etc

So, to use them you simply type

lss something
pss process, or process number, or process parent or any data you now it comes in the process line output
envv variable
etc.

Hope this helps.
Fernando

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (68.13.xx.xx) on Sun 1 May 2005 at 06:04
Minor clarification: don't bother including the '$1', it isn't doing anything in the above examples. Aliases in bash work on a simple string substitution mechanism.

If you want to do something more complicated, look at bash functions.

Note that the examples will still work (and are still very useful), the '$1' business is just a NOP.

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (62.13.xx.xx) on Fri 29 Apr 2005 at 13:54
Hi, my tip is for determinate the size of each directory (and files) and help me to know what is the bigger:

du -kx ./ | sort -n

Isn't a really bash tip, but it help me in my work ;)

my 2 cents

Marco Bertorello <marco(at)bertorello(dot)ns0(dot).it

[ Parent ]

Re: Question: Share your bash tips?
Posted by asg (24.93.xx.xx) on Fri 29 Apr 2005 at 15:50
Here's a useful little bashism if you are into non-portable shell scripting.
usage () {
        echo "usage: ${0##*/} "
        exit 1
}
The use of
${0##*/}
prevents one from having to shellout to basename(1).

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (65.26.xx.xx) on Thu 12 May 2005 at 23:14
Good news for you:

That's not a Bashism, it's standard POSIX shell.

The only non-POSIX shells that seem to be in wide use are csh and tcsh (which aren't descended from Bourne and Korn anyway), and Solaris sh.

Sadly, Solaris sh is a big reason for people continuing to use extrememly crude constructions in their "portable" shell scripts.

--Branden Robinson

[ Parent ]

Re: Question: Share your bash tips?
Posted by asg (24.93.xx.xx) on Fri 13 May 2005 at 11:37
Ah, thanks for the clarification.

--asg

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (82.197.xx.xx) on Fri 29 Apr 2005 at 16:01
pushd and popd can be useful when you're in a very deep patch tree and need to quickly do something somewhere else, and unlike cd - remains in place no matter how many directories you browse through:


sam@io:/usr/a/very/long/and/annoying/to/type/path$ pushd /etc/apache
/etc/apache /usr/a/very/long/and/annoying/to/type/path
sam@io:/etc/apache$ cd ssl
#Some more stuff here
sam@io:/etc/apache/ssl$ popd
/usr/a/very/long/and/annoying/to/type/path
sam@io:/usr/a/very/long/and/annoying/to/type/path$


^a and ^e (beginning of line and end of line) and ^w (delete word) are incredibly useful too.

[ Parent ]

Re: Question: Share your bash tips?
Posted by Steve (82.41.xx.xx) on Fri 29 Apr 2005 at 16:47
[ View Weblogs ]

Good example.

Of all the keyboard shortcuts the only ones I seem to use are:

^a   Beginning of the line.
^r   Search through history, backwards.
^k   Kill to the end of the line.
^u   Kill to the beginning of the line.

I never seem to have to move to the end of the line!

Steve
-- Steve.org.uk

[ Parent ]

Re: Question: Share your bash tips?
Posted by redbeard (64.218.xx.xx) on Wed 4 May 2005 at 17:19
[ View Weblogs ]

I use the following keyboard shortcuts frequently (in addition to some of the other mentioned shortcuts)

Meta-f  Forward one word
Meta-b  Backward one word
Meta-d  Delete forward one word

Of course, meta translates to Alt on PC keyboards (or the Esc, if you don't like pressing two keys at once :)

BTW, I just found the site (thanks to the Debian Weekly News). From what I've seen, I'll be using it a lot.

Michael

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (193.132.xx.xx) on Wed 13 Jul 2005 at 09:48
Thanks for this tip - I've been looking for the forward/backward shortcut for a while now. Alt doesn't seem to work though, only esc :|

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (195.126.xx.xx) on Mon 18 Jul 2005 at 14:43
Does anyone know how to map Meta-f and Meta-b to Meta-[left cursor] and Meta-[right cursor] ?
Ubuntu and Fedora (those I have used recently) do this out of the box, but not debian.
Regards,
Daniel

[ Parent ]

Re: Question: Share your bash tips?
Posted by redbeard (64.218.xx.xx) on Mon 18 Jul 2005 at 14:51
[ View Weblogs ]

From /etc/inputrc:

# mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving
"\e[5C": forward-word
"\e[5D": backward-word
"\e\e[C": forward-word
"\e\e[D": backward-word

I can confirm that it works.

[ Parent ]

Re: Question: Share your bash tips? $_
Posted by fugit (199.2.xx.xx) on Fri 29 Apr 2005 at 17:25
[ View Weblogs ]
I like to use $_ to access the last variable from the previous command.

keith@fugit:/tmp$ ls -la foo
-rw-r--r-- 1 keith keith 20 Apr 29 13:21 foo
keith@fugit:/tmp$ cat $_
This is some text.
keith@fugit:/tmp$

[ Parent ]

Re: Question: Share your bash tips? $_
Posted by Steve (82.41.xx.xx) on Sat 30 Apr 2005 at 21:45
[ View Weblogs ]

I previously used that a lot, but then I discovered 'Esc .' inserted it directly into the command line.

For me it's easier to remember to do that, as it allows editting when necessary.

Steve
-- Steve.org.uk

[ Parent ]

Re: Question: Share your bash tips? $_
Posted by Anonymous (137.208.xx.xx) on Mon 2 May 2005 at 07:36
funny, never knew the $_; but i knew this one:

shabbl:~# echo this > that
shabbl:~# cat !$
cat that
this

[ Parent ]

Re: Question: Share your bash tips? $_
Posted by mityollom (68.147.xx.xx) on Tue 3 May 2005 at 04:59
Here's a couple others along the same line:

If you can remember the number of the command in your bash_history, `!` will repeat that particular command in your history. i.e:

!4

Will repeat command number 4 in your history.

Typing `!` will repeat the last instance of that command in history. i.e if, the last 'cat' command issued was `cat /tmp/file`, typing this:

!cat

Will repeat the `cat /tmp/file` command again

Typing `!cat:p` will simply output the full command executed, and not actually execute it. This might be useful if you executed a large grep|awk|sort type thing and wanted to copy and paste a chunk of it into your next grep|awk|sort.

[ Parent ]

Re: Question: Share your bash tips? $_
Posted by Anonymous (83.201.xx.xx) on Sun 8 May 2005 at 16:19
I'd add the argument selection :

~# cat /etc/passwd
(look at it)

want to edit it ?

~# vi !-1:1
vi /etc/passwd

ESC "." is much more useful in this case, but sometimes you are glad to get just an argument of a previous command, not just the last one or the full command. E.g, using the third argument from the command before the last one :

~# cmd !-2:3


[ Parent ]

Re: Question: Share your bash tips? $_
Posted by Anonymous (32.97.xx.xx) on Fri 1 Sep 2006 at 19:49
You don't need "!-1:1" to refer to the argument of the previous command; just use "!:1".

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (195.178.xx.xx) on Fri 29 Apr 2005 at 21:44
you can with easily replace occurance of word1 with word2 in last command with ^word1^word2 here is example:
bilke@hydrogen:~$ ls /var
account  cache  local  log         mail  run    tmp  yp
backups  lib    lock   lost+found  opt   spool  www

bilke@hydrogen:~$ ^var^home
ls /home
bilke  export  ftp  igor  joejoe  lost+found  mirjam  pivo  samba

bilke@hydrogen:~$
best regards, bilke

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (69.17.xx.xx) on Sat 30 Apr 2005 at 19:36
On the whole I love bash_completion, but...

It's possible that this is only (or mostly) a problem with old, stable (Woody), which, yes, I still use on a number of machines where continuing to just work is more important than newer versions of things. All those servers in closets that might or might not even have monitors if an upgrade should go awry...

Anyway, with the fancy scripted completion turned on, I find that tab completion's leading side effect works less well, or sometimes not at all. That's hitting tab (twice) to see what all is in a directory. Very handy for context when groping for an obscure config file you haven't had to look at in a couple years, let me tell you. The failures seem to be erratic, aside from obvious things like only getting directories when the command is cd and so forth. On the whole the smarter tab completion seems well worth it, but there may be a few disruptions if you're already accustomed to using tab completion. - MartinManey

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (82.224.xx.xx) on Mon 2 May 2005 at 17:11
I have the following line in my ~/.inputrc:

"\e[Z": complete-filename

Therefore, TAB uses bash_completion and SHIFT+TAB performs a filename completion.

[ Parent ]

Re: Question: Share your bash tips?
Posted by butterblume (81.173.xx.xx) on Thu 26 May 2005 at 14:22
Well, if it's just a thing of habit or finger movement then just use Esc-= and Esc-Esc. This comes from the Emacs edit mode in the Korn Shell.

$ cd M[Esc-=]
Mail/ Mp3Kult/ Music/
$ cd Mu[Esc-Esc] => cd Music

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (81.41.xx.xx) on Mon 2 May 2005 at 11:19
I found very useful CTRL + l (it clears the screen)

[ Parent ]

Re: Question: Share your bash tips?
Posted by DaveV (24.8.xx.xx) on Sat 17 Sep 2005 at 21:39

That only clears the visible part of the terminal. You can still shift-PGUP to see what was there.

If you want to clear the terminal buffer so that they cannot shift-PGUP to see what was done do:

echo -en \\0033c

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (76.27.xx.xx) on Thu 6 Dec 2007 at 00:30
This has the same effect as the 'clear' command for me. ie, I can still shift-PGUP to see what was there. Using konsole, btw.

[ Parent ]

Re: Question: Share your bash tips?
Posted by orchid (64.26.xx.xx) on Mon 2 May 2005 at 16:29
[ View Weblogs ]
I like to set some shopt options in my .bashrc, particularly
shopt -s extglob
Then I can for example cd into a directory full of mp3s, and find any file that isnt an mp3..

ls -lh !(*.mp3)

[ Parent ]

Re: Question: Share your bash tips?
Posted by Steve (82.41.xx.xx) on Mon 2 May 2005 at 16:33
[ View Weblogs ]

That's very handy, and much simpler than my approach for the same gob:

ls -1 | grep -v \.mp3$

Although that works well for finding directories, with the following alias:

alias lsd='ls -l | grep ^d'

Steve
-- Steve.org.uk

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (200.201.xx.xx) on Tue 24 May 2005 at 17:54
I find directories using

ls -ld */


Nosklo

[ Parent ]

Re: Question: Share your bash tips?
Posted by stew (216.254.xx.xx) on Mon 2 May 2005 at 21:30

To change to the previous directory just run:

cd -


Along the same lines, you can refer to the previous PWD as "~-" for example:

cd /etc/ ; cd /tmp ; cp ~-/passwd . ; will copy /etc/passwd to /tmp/passwd

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (212.204.xx.xx) on Tue 3 May 2005 at 20:10
Commandlines not appearing in the history file:

Well, I,m not sure if this one is really necessary - except in cases, when you are forced to write sensitive data as an option in a command like passwords *shudder* - but it may be good to know, that there are environment variables, with which you can control the behaviour of saving commands to the history file: one way is to set

$ HISTCONTROL=ignorespace

Afterwards you can type commands beginning with a space, that will not show up in your history file.

$ ll
.... lot of files
$ _ls -a
.... again lot of files
[UP]
$ ll

Many more things are possible. Just "man bash" and "/HISTCONTROL".

Best regards and thanks for hints of many I didn't know ;-))

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (199.4.xx.xx) on Tue 3 May 2005 at 20:37
For years I was a bash fan, and used autocompletion a lot. But now I've converted to zsh(1). zsh autocompletion doesn't seem to be such a hack to me, and I perceive it as quicker. And zsh has much better meta-chars. For example ls **/*.c will list all c files in all subdirectories of the current one, *recursively*. Much nicer than find . -name '*.c' -ls.
(BTW I am comparing to bash 2.05; maybe bash 3 is better.)

Will

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (67.76.xx.xx) on Sun 16 Oct 2005 at 08:35
/usr/src/linux-2.6.11.5$ ls -1 */*.c | tail
security/dummy.c
security/root_plug.c
security/root_plug.mod.c
security/seclvl.c
security/security.c
sound/last.c
sound/sound_core.c
sound/sound_firmware.c
usr/gen_init_cpio.c
/usr/src/linux-2.6.11.5$ echo $BASH_VERSION
3.00.16(1)-release
/usr/src/linux-2.6.11.5$ cat /etc/debian_version 
testing/unstable

[ Parent ]

Re: Question: Share your bash tips?
Posted by jml (212.113.xx.xx) on Tue 3 May 2005 at 22:27
A features I use frequently is Alt-T, that switches the word under the cursor with the previus one. Ex: with the cursor over 'that', "this that"+Alt-T becomes "that this".

And another one a use very frequently is brace expansion. Ex: "echo a{1,2,3}" prints "a1 a2 a3" on the screen. Very useful for: "mv /a/very/long/pathname{,.OLD}"

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (145.222.xx.xx) on Wed 4 May 2005 at 11:22
You wrote:
[...]
To cause your shell to use it run the following command, then login again:
echo '. /etc/bash_completion' >> ~/.bashrc
[...]

Do you actually have a reason to login again after editing your .bashrc?
You don't have to, just use the same command as you just added to your .bashrc, but now with your just edited .bashrc.
Just run:
. .bashrc
And .bashrc is executed in your current shell instead of in a subshell.

my 2 cents,
Nok

[ Parent ]

Re: Question: Share your bash tips?
Posted by rmcgowan (143.127.xx.xx) on Wed 4 May 2005 at 17:58
Simpler yet, just do the sourcing of the file from you shell command prompt:

. /etc/bash_completion

It's possible that your .bashrc might contain something you only want done once, when your shell starts up.

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (217.113.xx.xx) on Mon 9 May 2005 at 22:04
Or... make all users happy all the time :) and uncomment it in /etc/bash.bashrc

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (141.52.xx.xx) on Wed 4 May 2005 at 11:38
I'm ssh'ing and scp'ing a lot, so I define my prompt to be
'[\u@\h:\w]$ '. This makes it much easier to copy/paste user@host:/path to other shell windows.

In order to keep all bash configuration in sync on many hosts my .bashrc sources a couple of files that are kept in cvs. One of those files is a 'cvs update' :-)

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (83.201.xx.xx) on Sun 8 May 2005 at 16:29
If you use xterm (or another term emulator) a lot, try adding this in your .bashrc (especially if you connect to a lot of remote machine, but don't forget to add it to the *remote* bashrc)

# If this is an xterm set the title to user@host:dir
case $TERM in
xterm*)
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
;;

*)
;;
esac


This way, the title of the term will be updated when you change host, dir or user.

Also, if you use ssh/scp a lot, bash_completion complete hosts and remote filenames by default if you use ssh-agent:

scp local_file root@hTAB/remTAB/paTAB
would then expand as :
scp local_file root@host:/remote/path/

you'll need of course a fast and low-latency connection for it to be useful. Waiting several seconds after typing TAB becomes annoying with time ;)

[ Parent ]

Re: Question: Share your bash tips?
Posted by ibroadfo (130.159.xx.xx) on Wed 4 May 2005 at 14:13
my .inputrc:
set completion-ignore-case On #tab complete without needing to get the case right
set show-all-if-ambiguous On #show list on first tab, no need to hit tab again
set visible-stats On # not sure what this one does...
set mark-symlinked-directories On # handy

Now, some functions from my .bashrc:

These are just nice shortcuts for searching for a string in filenames under the current directory
findme() { find -iname "*$@*" -or -iname ".*$@*"; }
findmewhole() { find -iwholename "*$@*" -or -iwholename ".*$@*"; }

This takes a string and provides a top-like display of matching lines from ps. The 'grep -v grep' bit is because otherwise the 'grep -i $@' line matches itself!
running() { watch -n1 "ps aux | grep -i $@ | grep -v grep"; }

iain

[ Parent ]

Re: Question: Share your bash tips?
Posted by rmcgowan (143.127.xx.xx) on Wed 4 May 2005 at 18:28

It doesn't look like there are too many of us 'vi' mode users based on the responses I saw.

But, if you do use the VI edit mode (set -o vi) be aware that you cannot use the 'ESC-...' stuff mentioned here for EMACS mode.

For example, the 'ESC-.' that fills in the last arg from the prior command for EMACS mode, will repeat the last edit if in VI mode. So:

cp[ESC-.]

produces:

cpcp

Which is probably not too useful ;)

Bob

[ Parent ]

Re: Question: Share your bash tips?
Posted by ibroadfo (130.159.xx.xx) on Thu 5 May 2005 at 10:06
yeah, I find vi mode quite hard at the shell: the keys don't seem to flow for me at all.

emacs mode works fine though.

The strange thing is that I use vim for all my text editing needs...

iain

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (83.201.xx.xx) on Sun 8 May 2005 at 16:38
Do you rekon it means vim is meant for text editing, not to be confused with a shell or an OS ? ;)

Ok, now that the troll part is done, I'd say that vi mode is for me actually unusable in the CLI, even though I'm a lot more acustomed to vim than to emacs.

but sometimes I find myself typing ESC afer a command, then :x to quit the shell ;)

[ Parent ]

Re: Question: Share your bash tips?
Posted by ibroadfo (62.252.xx.xx) on Sun 8 May 2005 at 16:47
> Do you rekon it means vim is meant for text editing, not to
> be confused with a shell or an OS ? ;)

Yeah, vim isn't as useful a shell or OS as emacs is.

:p

iain

[ Parent ]

Re: Question: Share your bash tips?
Posted by rompe (84.130.xx.xx) on Thu 12 May 2005 at 11:31
Sometimes I like to use vi to edit complex. Therefore I set the EDITOR variable to /usr/bin/vim and to load the last executed command line into vi I just type:
fc
The command line is executed immedietly after I quit vi.

You can use any editor you like, but it should not fork itself into a new process. To test this, run your editor from the command line, and if your shell prompt returns before you quit the editor window, you can't use it for things like this.

[ Parent ]

Re: Question: Share your bash tips?
Posted by dkg (216.254.xx.xx) on Fri 26 Aug 2005 at 05:29
[ View Weblogs ]
This is a great tip. You can also use C-x,C-e to invoke your $EDITOR on the currently active command line. i'm trying to train myself to do that when what i thought was going to be a simple bash directive gets too unwieldy.
do remember that whatever you type is going to be executed when the editor closes, though! that can sometimes be a surprise.

[ Parent ]

Inline comment
Posted by Anonymous (84.133.xx.xx) on Thu 12 May 2005 at 21:13
Imagine a shell script with some compiler call like

gcc -O99 -march=formula1 and-some-more-things

and you want to strip away the -O99 option remembering what was there:

gcc $(# -O99 ) -march=formula1 and-some-more-things

[ Parent ]

Re: Inline comment
Posted by Anonymous (86.33.xx.xx) on Mon 9 Mar 2009 at 01:16
I was looking for the bash feature "inline-comment" very long!
Especially for commenting on arguments, which must be in one line, except if the line end is escaped, but then again technically to the shell it is still one line.

My disappointment was very big, when it didn't work.

I used bash 3.2.17(1)-release (i386-apple-darwin9.0) on MacOSX 10.5.5 and none of the following worked.
I tried the brackets without spaces, with only a space after the opening bracket, and then a space after/before both brackets.

ls -l $(#display-as-list) -a $(#all) -H $(#human readable)
ls -l $( #display-as-list) -a $( #all) -H $( #human readable)
ls -l $( #display-as-list ) -a $( #all ) -H $( #human readable )

[ Parent ]

Re: Inline comment
Posted by Anonymous (70.111.xx.xx) on Sat 25 Apr 2009 at 10:04
It does work (OSX 10.4.11, bash 2.05b default).

It's just like the op said. $(# text ).
Number sign, space, text, space.

[ Parent ]

Re: Inline comments still do not work on Mac OS X 10.5.8 bash shell
Posted by Anonymous (86.32.xx.xx) on Fri 2 Dec 2011 at 13:14
On Mac OS X 10.5.8 with bash 3.2.48,
neither your stated writing form,
nor any of its various permutations worked!

All these commands failed:

ls -l $(#displayaslist) .
ls -l $(#displayaslist ) .
ls -l $(# displayaslist) .
ls -l $(# displayaslist ) .

ls -l $( #displayaslist) .
ls -l $( #displayaslist ) .
ls -l $( # displayaslist) .
ls -l $( # displayaslist ) .

[ Parent ]

Quick and dirty backups and working with diffs
Posted by Anonymous (65.26.xx.xx) on Thu 12 May 2005 at 23:27
I frequently use Bash's brace expansion for preparation of quick-fix patches, or preparation of fixed diffs that correct patch failures.

Example:
# Make a backup of xterm.c.
$ cp xterm.c{,~}
# Patch it.
$ patch -p0 </tmp/xterm_patch.diff
# Get warned about offsets, fuzz, and rejected hunks.
# Use vim to hand-merge rejected hunks.
$ vim -O xterm.c{,.rej}
# Create new diff that applies cleanly.
$ diff -u xterm.c{~,} >/tmp/good_xterm_patch.diff

I have found that simple use of brace-expansion like this saves me a lot of typing. Even tab-completion can get tedious if you're operating on things deep within a directory structure, and for whatever reason don't want to cd in there. (Think xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c.)

--Branden Robinson

[ Parent ]

Many many domain aliases.
Posted by stevenothing (81.6.xx.xx) on Sat 21 May 2005 at 12:13
That can be especially useful when adding virtual hosts in apache config files for people who have to register every single possible combination of a domain name they can.

in vim:

:r! echo ServerAlias {www.,}domain{-,}part.{com,biz,net,info,me,name,{org,co}.uk}

[ Parent ]

Re: Many many domain aliases.
Posted by Anonymous (67.76.xx.xx) on Sun 16 Oct 2005 at 08:46
Doesn't work.
~$ vim --version | grep compiled
VIM - Vi IMproved 6.3 (2004 June 7, compiled Sep  1 2005 16:51:12)
~$ echo $BASH_VERSION
3.00.16(1)-release

[ Parent ]

Re: Many many domain aliases.
Posted by Anonymous (84.12.xx.xx) on Mon 17 Oct 2005 at 08:29
It seems to work on my slightly older versions:

VIM - Vi IMproved 6.3 (2004 June 7, compiled Apr 24 2005 15:44:11)
bash version: 2.05b.0(1)-release

What about something like:

:r! /bin/bash -c 'echo {www.,}foo{-,}bar.{com,net}'

And take it from there? And if that doesn't work, try it at the command line (where it should definitely work), and if not, find out what's wrong with bash's brace expansion.

[ Parent ]

Performing actions on multiple files
Posted by Anonymous (205.200.xx.xx) on Sun 29 May 2005 at 18:06
A few months back I blogged about how I perform mass file actions in bash (i.e. how to execute a sequence of commands on multiple files). It's not rocket science, but is a pattern I use frequently and is useful for beginners to know.

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (149.217.xx.xx) on Tue 7 Jun 2005 at 14:50
The complete list of bash completed applications can be found here: http://www.hypexr.org/bash_tutorial.shtml#completion

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (80.184.xx.xx) on Sat 11 Jun 2005 at 12:18
very useful in any situation :)

CTRL + SHIFT + _ UNDO

[ Parent ]

Re: Question: Share your bash tips?
Posted by simono (80.198.xx.xx) on Thu 23 Jun 2005 at 05:36
If you need to do something to a lot of files or directories you can use:
for fileordir in `ls /some/dir`;
do
somecommand $fileordir;
someothercommand $fileordir;
done

Use ctrl+z to stop a running process and bg to start in in the background.

Use ctrl+u to cut left, ctrl+k to cut right, and ctrl+y to insert the cutted text/command.

some nice variables:
$RANDOM contains a random number. Really useful for creating tempfiles in bash scripts

$? contains exit status of last process executed.

The while loop is nice if you need to check the status of something and do something if the status change.

Test commands list -z $SOMEVAR to see if $SOMEVAR is an empty string or undefined.

--Simon Østengaard

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (201.128.xx.xx) on Fri 8 Jul 2005 at 04:48
All that comments about Ctrl-key make something is because bash behaves like emacs and some commands have similar functions. In fact, bash has 2 modes of operation, the emacs mode (default) and the vi mode (i have never used that). This is a list of commands in the emacs mode that i remember:

Ctrl-a -> go to the start of command line
Ctrl-e -> go to the end of command line
Ctrl-p -> previous command in history
Ctrl-n -> next command in history
Ctrl-f -> next character in command line
Ctrl-b -> previous character in command line
Ctrl-r -> reverse search in history file
Ctrl-d -> delete current character
Ctrl-k -> delete from the prompt to the end of command line
Ctrl-_ -> undo (yes, but limited)
Meta-< -> go to beginning of history file
Meta-> -> go to end of history file
Meta-f -> go to next word in command line
Meta-b -> go to previous word in command line
Meta-d -> delete next word in command line (from the actual position of the prompt)


and that's all i can remember. There is a lot more, you can find that in books about bash (oreilly i think).

Enjoy! ;-)

[ Parent ]

Re: Question: Share your bash tips?
Posted by DaveV (24.8.xx.xx) on Mon 8 Aug 2005 at 03:42

Handy little trick for vim and bash.

To open the last file you edited, just alias:

alias lvim="vim -c \"normal '0\""

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (196.30.xx.xx) on Wed 24 Aug 2005 at 13:23
To search forward for a specific character
ctrl-] character
To seach backward
esc ctrl-] character

Anyone know how to repeat the search..

[ Parent ]

Re: Question: Share your bash tips?
Posted by markiemark (67.184.xx.xx) on Fri 23 Sep 2005 at 16:59
I'm particularly fond of bash's ability to do net-redirections (which is purely dependant on the distribution your using as some distros enable it by default, while most don't, hence you'll have to recompile bash using the --enable-net-redirections flag, see documentation).

[ Parent ]

Keeping History of Visited Directories and BASH Arrays
Posted by astrodonki (24.131.xx.xx) on Thu 13 Oct 2005 at 20:59

I wanted BASH to keep a list of all the directories I visited so that
I could jump to any visited directory by providing a few characters from its name or even go back and forth through the list of visited directories.

Now, BASH already provides a few things that I could use:

1) I could use CDPATH environment variable
If I put in my .bashrc someting like

export CDPATH="/path/dir:/path/dir2"

Next time I do 'cd blah' BASH will check /path/dir and /path/dir2 to see if any of their sudirectories is 'blah'. But every time I create a new directory that has subdirectories of my interest I need to update CDPATH and restart my terminal. Not to mention that NOT all subdirectories will be of my interest so if I have a few 'bin' sudirectories, and I do 'cd bin' BASH will go to the first one found. CDPATH is useful but it's quite annoying if it sends you to the wrong directory.

2)'cd -' can take you to the previously visited directory. But I want more than that. I want to be able to go through the entire history of visited directories.

*) If you know of any other method that pertains to my problem, let me know.

MY SOLUTION

Well, it took me some time but I figured out how to do it.
First I needed to use BASH lists (BASH Arrays).

Arrays are declared like this:

arr=(zero one two three four)
echo ${arr[0]} # gives zero
echo ${arr[@]} # lists entire array as one string
echo ${#arr} # gives the number of elements in an array

Of course, you can combine it with a different input.

arr=(`ls`) # grabs the output of 'ls' into an array
arr=(`cat myfile`) # grabs the file into an array
# every line from the file is assigned to one array element

Little tangent on delimiters
-----------------------------
Strings from `cat myfile` are delimited based on \n (new line)
that is why our 'arr' takes one whole line per element.
If you want your strings to be delimited in some other way,
use IFS="/", where '/' will become a delimiter

If you put in your .bashrc
IFS="
"
then the newline \n will become a delimiter again
(This business with IFS could be a pain.)
-----------------------------

I also needed to do some arithmetic in here, for which I used the
double parentheses expression: (( math ))

m="1" # always use "", even for numbers
((m++)) #increments m
((m--)) #decrements m
((n=m+3))
echo "m=$m n=$n" #gives m=1 n=4

Before the code: How to Use it
-------------------------------
This is how you can use my code below.
You need to put it in .bashrc and restart the terminal.
Suppose you have some directories:
MyDocuments, Test, CodeOfMyProject and its subdir "Two words".

cd MyDocuments # now the history has remembered MyDocuments
cd # You go back to ~
cd Test # Test is also remembered
# And so on for every directory you visit
......

dir save # saves the history into .dir_history in your home directory
# Now every time you open a terminal this history will be loaded
# so you don't have to type it again

cd Two # Sends you to CodeOfMyProject/Two words
cd .. # Sends you to CodeOfMyProject
cd # Sends you home ~
cd - # Sends you backwards in history to CodeOfMyProject
cd - # Sends you backwards again to CodeOfMyProject/Two words
cd + # Sends you forwards in history
cd T # Sends you to Test
# NOTE: all forward history is now deleted
think of it the way web browsers behave!
dir load # loads the history (if you don't want it to load automatically)
cd My # Sends you to MyDocuments

ANOTHER NOTE: If you want to use a regular 'cd' command type \cd
The same thing applies to \dir

c # The alias 'c' will allow you to choose a dir from a list
dir choose # Does the same thing as 'c'

dir clear # clears history

THIRD NOTE: I made the search case sensitive. You can make it insensitive by adding an -i option in 'grep -E $regexp'

FINAL NOTE: If you have too many directories in history the search might become slow. I guess I will add some upper limit on how many directories you can have in history. Also, the history will NOT save itself. You have to do 'dir save'.
You can also put 'dir save' in .bash_logout

NOW THE CODE:
--------------

# put this in your .bashrc to see how it works
# I tried to make useful comments
# but you are welcome to delete them


# -----SECTION: Moving through directories --------

# declaring variables
export dirarr dircnt dirarr_fhist dircnt_fhist

# dirarr is where I keep visited directories (no duplicates)
# dircnt is its length, ${#arr} was giving me some trouble
# dirarr_fhist a an array of forward history

if [ -z $dircnt ]
then dircnt="1"
dirarr=("`pwd`")
fi

if [ -z $dircnt_fhist ]
then
dircnt_fhist="0"
dirarr_fhist=
fi

# some aliases that will save us the trouble of too much typing
alias cd='push'
alias p='push'
alias o='pop'
alias c='choose'
alias dir='dir_utility'

# loads and saves history,
# lists and chooses directories
dir_utility() {

case "$@" in

s|sa|sav|save)
save_dirhist
;;
lo|loa|load)
load_dirhist
;;
l|li|lis|list)
dirl
;;
c|ch|cho|choo|choos|choose)
choose
;;
*)
\dir "$@"
;;
esac
}

# Used by push() function (see below)
pop() {
popd "$@" > /dev/null
}

# This is where 'cd' command is parsed
push(){

case "$@" in
"")
pushd ~ > /dev/null
;;

"-") # going backward in history
prevdir="`pwd`"
popd > /dev/null
dirarr_fhist[$dircnt_fhist]=$prevdir
((dircnt_fhist++))
;;

"+") # going forwards in history
if [ "$dircnt_fhist" == "0" ]
then
echo "Forward list empty"
return 1
fi
((dircnt_fhist--))
dir=${dirarr_fhist[$dircnt_fhist]}
if [ ! -z $dir ]
then
pushd "$dir" > /dev/null
fi
;;

*) # parsing cd
if [ -a "$@" ]
then
pushd "$@" > /dev/null
clear_fhist
curdir="`pwd`"
for ((i=0; $i < $dircnt; i++)); do
if [ "${dirarr[$i]}" == "$curdir" ] ; then
return
fi
done
dirarr[$dircnt]="$curdir"
dircnt=$((++dircnt))
else
cdpartial "$@"
fi

;;
esac

export dirarr dircnt
export dirarr_fhist dircnt_fhist

}

# list history
dirl() {
for ((i=0; $i < $dircnt; i++))
do
if [ "$1" == "-n" ] ; then
echo -e "${dirarr[$i]}\n"
else
echo "${dirarr[$i]}"
fi
done
}

# choose a directory from history
choose() {

if [ ! -z "$1" ] ; then
if (( $1 >= 1 && $1 <= $dircnt )) ; then
num=$1
((num--))
pushd "${dirarr[$num]}" > /dev/null
clear_fhist
return 0
fi
fi


# make IFS take \n as a separator
IFS="
"
PS3="jump to directory # "
select dir_ans in `dirl -n`
do
if [ ! -z $dir_ans ]
then
pushd "$dir_ans" > /dev/null
clear_fhist
break
fi
done
}

# save history
save_dirhist() {
dirl | sort > ~/.dirhistory
}

#load history
load_dirhist() {
# this should go to .bash_login
if [ -r ~/.dirhistory ]; then
# TODO Test validity of directories
#cat .dirhistory | while read line
#do
# echo $line
#done
IFS="
"
dirarr=(`cat ~/.dirhistory`)
#dircnt=${#dirarr} #NOT WORKING
dircnt="`cat ~/.dirhistory|wc -l`"
fi
}

# find a directory in History based on a partial string
cdpartial() {
if [ $dircnt -eq 0 ]
then return
fi

for ((i=0; $i < $dircnt; i++))
do
regexp="$@[^/]*$"
if [ `echo ${dirarr[$i]}| grep -E $regexp | wc -l` -gt 0 ]
then
\cd ${dirarr[$i]}
clear_fhist
return
fi
done
echo "$@: directory not found"
}

# clears forward history
clear_fhist() {
export dirarr_fhist=
export dircnt_fhist="0"
}

# clears history
clear_hist() {
export dirarr=
export dircnt="0"
}

# loads history in .bashrc
load_dirhist

# -----END SECTION: Moving through directories --------

# P.S. I'm using the newest BASH - 3.x

[ Parent ]

Re: bash tips
Posted by Anonymous (24.206.xx.xx) on Tue 22 Nov 2005 at 23:37
I maintain a short page of bash tips here. Compare, for example, my cd setup with the comment above.

[ Parent ]

apt-alias
Posted by m_ (217.224.xx.xx) on Sat 21 Jan 2006 at 13:20
i found it useful to add some aliasses to apt-get/apt-cache for commands i use a lot, which i find do not only save some time, but to me even seem a little more intuitive. in my .bashrc i have:


# apt-aliases
alias apt-search="apt-cache search"
alias apt-policy="apt-cache policy"
alias apt-install="apt-get install"
alias apt-remove="apt-get remove"
alias apt-clean="apt-get clean"
alias apt-update="apt-get update"
alias apt-upgrade="apt-get upgrade"


this has proven to lower the confusion for novices i introduced to debian administration, when i comes to package management.

hope you find it helpful, too.

[ Parent ]

Re: apt-alias
Posted by ajt (204.193.xx.xx) on Thu 31 May 2007 at 10:29
[ View Weblogs ]
I've done a similar thing, only I used apitude instead apt-get and put the sudo in it. I also created an all in one update/clean/upgrade for my testing box, as that's what I do most often.

--
"It's Not Magic, It's Work"
Adam

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (63.20.xx.xx) on Sun 6 Jul 2008 at 20:05
I find CTRL+Z and fg quite handy. An example:

~$ some-big-heavy-long-running-cmd
CTRL+Z

~$ do-something-else
....

~$ fg
results of some-big-heavy-long-running-cmd

[ Parent ]

Re: Question: Share your bash tips?
Posted by Anonymous (89.182.xx.xx) on Fri 10 Oct 2008 at 16:06
ls -Alah
and
grep -Hirn string *

[ Parent ]