# Any nifty shell tricks to share?



## lockfile (Dec 27, 2012)

I was mucking around with the shell today. Doing some file management by hand. And I just edited a few history commands manually and then ran them. It was exhilerating. Any nifty shell tricks you guys have that you use?

I use bash mostly, but anything done in one shell can be done in another, with enough voodoo anyway.


----------



## bbzz (Dec 27, 2012)

Look at 'Useful shell scripts' thread or something along those lines.


----------



## vermaden (Dec 27, 2012)

> Any nifty shell tricks to share?



I mostly use these:


```
% [color="Blue"]cd -[/color] [color="Silver"](go to last used directory, also known as ${OLDPWD}, as compared to current working dir - ${PWD})[/color]
% [color="blue"]cd ~[/color][color="silver"] (go ${HOME})[/color]
% [color="Blue"]ls DIR[/color]
% [color="blue"]cd !$[/color] [color="Silver"](means last argument of last command - DIR in that case)[/color]
% [color="Blue"]^DIR^other[/color] [color="Silver"](execute last command, but replace 'DIR' into 'other')[/color]
% [color="Blue"]!3[/color] [color="Silver"](execute command from history with id 3 - 'ls DIR' in our case)[/color]
% [color="Blue"]./some-long-running-thing[/color] [color="Silver"](now hit CTRL-Z, also known as ^Z to suspend it)[/color]
[color="Blue"]^Z[/color]
zsh: suspended  ./some-long-running-thing
% [color="blue"]jobs[/color][color="Silver"] (list jobs)[/color]
[1]  + suspended  ./some-long-running-thing
% [color="blue"]bg %1[/color] [color="silver"](put job 1 into background)[/color]
[1]  + continued  ./some-long-running-thing
% [color="blue"]fg %1[/color] [color="silver"](put back 1 into foreground)[/color]
[1]  + running    ./some-long-running-thing [color="silver"](again hit CTRL-Z)[/color]
[color="blue"]^Z[/color]
zsh: suspended  ./some-long-running-thing
% [color="blue"]bg %1[/color] [color="silver"](put into background)[/color]
[1]  + continued  ./some-long-running-thing
% [color="blue"]disown[/color] [color="silver"](detach that job from this terminal - it will not be closed as you close this session - in other words, poor man's screen/tmux)[/color]
% [color="blue"]jobs[/color] [color="silver"](no jobs)[/color]
% [color="Blue"]kill -9 $$[/color] [color="silver"](kill this terminal session without writing to the history file)[/color]
```

I also use several aliases, the most popular I use is query (q/Q) - for case sen/insensitie ls|grep someting):


```
% [color="blue"]which q[/color]
q: aliased to ls | grep -i  2> /dev/null
% [color="blue"]which Q[/color]
Q: aliased to ls | grep  2> /dev/null

% [color="blue"]Q BSD[/color]
[B][color="Lime"]BSD[/color][/B]mag-formatting-rules.pdf

% [color="blue"]q bsd[/color]
[B][color="lime"]BSD[/color][/B]mag-formatting-rules.pdf
[B][color="lime"]bsd[/color][/B]mag-notes.txt
```

The colored grep(1)() is also useful:


```
% [color="blue"]which grep[/color]
grep: aliased to grep --color
% [color="blue"]env | grep GREP[/color]
GREP_COLOR=1;32
```


```
% [color="blue"]dmesg | grep BSD[/color]
Copyright (c) 1992-2012 The Free[B][color="lime"]BSD[/color][/B] Project.
Free[color="lime"][B]BSD[/B][/color] is a registered trademark of The Free[color="lime"][B]BSD[/B][/color] Foundation.
Free[color="lime"][B]BSD[/B][/color] 9.1-PRERELEASE #0 r243107: Fri Nov 16 07:41:05 CET 2012
Free[B][color="lime"]BSD[/color][/B]/SMP: Multiprocessor System Detected: 2 CPUs
Free[color="lime"][B]BSD[/B][/color]/SMP: 1 package(s) x 2 core(s)
```

I also use the ZSH shell which helps a lot, but FISH shell is also quite nice.


----------



## kpedersen (Dec 27, 2012)

The following is perhaps a bit lame, but so far is the only way I know to reliably find the exact directory name where a script is running.


```
THIS=`which "$0"`
PREFIX=`dirname "$THIS"`

echo "$PREFIX"
```

Very useful when you need it


----------



## throAU (Dec 27, 2012)

Top tip:  learn regular expressions, awk, sed and grep


----------



## UNIXgod (Dec 27, 2012)

throAU said:
			
		

> Top tip:  learn regular expressions, awk, sed and grep



ed() and ex() also!


----------



## lockfile (Dec 27, 2012)

All good tips.


----------



## vermaden (Dec 27, 2012)

kpedersen said:
			
		

> Very useful when you need it



[*] will work only if that script is in the PATH (which).


----------



## kpedersen (Dec 27, 2012)

vermaden said:
			
		

> [*] will work only if that script is in the PATH (which).



The `which` is to find the full path *if* the script was run from PATH, however, which still returns a relative path if the target is not in PATH.


```
$ which testy
  no testy in ...

$ which /home/kpedersen/somefolder/testy
  ~/somefolder/testy

$ which somefolder/testy
  ./somefolder/testy
```

... and now for the awesome one...


```
$ cd somefolder/someotherfolder/morefolders
$ which ../../testy
  ~/somefolder/testy
```

Which (pun intended) is quite cool.

Note: As you can see, which sometimes returns a path starting with "~/". I prefer a full path so that is why I use the `dirname` on it afterwards.

Then yes, you would need to `cd` into the PREFIX of my previous script and do a `pwd` if you want to find an absolute path (from /). Though since my main reason for doing the above to is source config files that the script needs, I rarely need to do this. e.g.


```
ORIG=`pwd`
THIS=`which "$0"`
PREFIX=`dirname "$THIS"`
cd "$PREFIX"
ABSOLUTEDIR=`pwd`
cd "$ORIG"

echo "$ABSOLUTEDIR"
```

Try placing this around anywhere on your filesystem and it shouldn't ever have an issue finding it's parent directory, if it is in PATH or not.


----------



## fonz (Dec 27, 2012)

vermaden said:
			
		

> % ^DIR^other (execute last command, but replace 'DIR' into 'other')


I usually use tcsh(1), but the above is indeed a very nice bash feature.

Fonz


----------



## jalla (Dec 27, 2012)

fonz said:
			
		

> I usually use tcsh(1), but the above is indeed a very nice bash feature.
> 
> Fonz



The ^foo^bar construct is standard csh stuff. It's shorthand for

`!:s,foo,bar`


----------



## fonz (Dec 27, 2012)

jalla said:
			
		

> The ^foo^bar construct is standard csh stuff. It's shorthand for
> 
> `!:s,foo,bar`


Gee, I'm familiar with the latter but had no idea that the former works as well. Thanks for pointing that out.

Fonz


----------



## Michael-Sanders (Dec 28, 2012)

I really do enjoy reading & learning from others snippets, thanks for sharing folks. Here's hybrid (dual propose) alias I use:


```
# if x is not running, then invoke startx, else close current xterm:
alias x "[ x$DISPLAY  = 'x' ] && startx || exit"
```


----------



## Michael-Sanders (Jan 16, 2013)

One line jukebox...

As root... play all mp3's on all mounted drives randomly (uses audio/mpg123 or audio/mpg321):


```
sudo find / -type f -iname '*.mp3' | mpg123 -z@ -
```


----------



## Michael-Sanders (Jan 16, 2013)

Repeat last sudo command:


```
sudo !!
```


----------



## Michael-Sanders (Jan 16, 2013)

use grep to highlight match & show entire line:


```
grep --color -E 'pattern|$' file
```


----------



## Michael-Sanders (Jan 16, 2013)

Just discovered something about grep's -color option... it appears '--color' will not work within a pipe -unless- you specify the 'always' flag as shown below. Now we have color when piped to less when used with the '-R' switch (display ANSI color escape sequences):


```
grep --color=always -E 'pattern|$' file | less -R
```


----------



## jb_fvwm2 (Jan 16, 2013)

*Brand new CLI today from the freebsd-ports list*

HOW did I know as of just then that twelve installed ports are scheduled for removal?

```
export $PORTSDIR='/usr/ports'   # probably a different syntax for other shells, unless set already, setenv?
....
cd /usr/ports  # is the ports tree recent?
...
# don't know the [FILE]pkg info [/FILE] cli...
pkg_info -qoa | xargs -I @ grep -le EXPIRATION_DATE $PORTSDIR/@/Makefile
```
The ports one may have installed that are schedule for deletion should be echoed, one per line,
to the screen (not an error message from pkg_info, which may also occur...


----------



## jalla (Jan 16, 2013)

Michael-Sanders said:
			
		

> Repeat last sudo command:
> 
> 
> ```
> ...



I think you mean

```
!sudo
```


----------



## fonz (Jan 16, 2013)

jalla said:
			
		

> I think you mean
> 
> ```
> !sudo
> ```


To clarify:
`% !sudo`
repeats the last command issued through sudo.
`% sudo !!`
repeats the last command but with sudo prepended (which basically means "repeat the last command but this time sudo it", handy if you tried the command itself but forgot to use sudo).

Fonz


----------



## Michael-Sanders (Jan 17, 2013)

jalla said:
			
		

> I think you mean
> 
> ```
> !sudo
> ```



Yes, my example could've been better described...


----------



## throAU (Jan 17, 2013)

Another top tip for csh users.

Set up your prompt to start with a *:* and end with a *;*

Why?  It will cause the shell to ignore your prompt if it is cut/pasted.

This means you can select multiple lines of commands on the screen/terminal window with your mouse and cut/paste the whole lot (assuming there is no screen output between them, you'd need to not select that).

e.g., my prompt on one of my boxes is thus:


```
: 13:02, proxy, /root ;
```

So if I simply double click a line to highlight the entire line, I can simply cut/paste that to repeat the command.  Or multiple lines...

It is also colour coded in BLUE if I am root, and GREEN if I am not root, so it is abundantly clear to me whether or not I am root when clicking in a terminal window whether or not I read the prompt.

The actual .cshrc code for my csh root prompt (blue) is

```
set prompt = '    : %{\033[1;34m%}%T, %m, %/%{\033[0m%} ; '
```

You can mess with the ASCII escape codes to select the colour of your choice.


----------

