Shell-Hacks
From NetBSD Wiki
You can share your shell hacks here.
Convert DOS or Windows Textfiles to Unix and back
From DOS to Unix:
$ sed 's/^M$//' < dos.txt > unix.text OR $ sed 's/.$//' < dos.txt > unix.text
From Unix to DOS:
$ sed 's/$/^M/' < unix.text > dos.txt
Separate Filenames
To separate the filename from a full path, you can use the shell command basename.
$ basename /home/matthias/resize.sh resize.sh
You can cut the extension aswell:
$ basename /home/matthias/resize.sh .sh resize
You can also use a shell feature :
$ FILENAME="/home/matthias/resize.sh"
$ basename ${FILENAME%%.sh}
resize
This works for extensions that are known in advance. For unknown extensions try this:
$ FILENAME="/home/matthias/resize.py"
$ basename $FILENAME .`echo $FILENAME|awk -F . '{print $NF}'`
resize
Show the Current Command in the xterm Title Bar (zsh)
It's nice to be able to identify a terminal by the currently running command, especially if you have a few of them open. Additionally, the username, hostname and the working directory is displayed. This is no problem with a proper shell. Add this to your .zshrc:
# TitleBar setting
case $TERM in
xterm*)
preexec () {print -Pn "\e]0;%n@%m [$1] [%~]\a"}
;;
esac
It will show the xterm title "root@robowork [portupgrade -a] [/usr/ports]". Explanation: preexec() is defined. This function is called by zsh before executing a command. Terminal emulators should react accordingly.
Effective Renaming (zsh)
We want to rename following files from 'txt' to 'tex' :
%> ls *.txt bp_ccc.txt bp_xxx.txt bp_yxc.txt bp_yyy.txt
Solution using zsh feature zmv (.zshrc: "autoload zmv") :
%> zmv -W "*.txt" "*.tex" %> ls *.tex bp_ccc.tex bp_xxx.tex bp_yxc.tex bp_yyy.tex
Option W automatically converts the data of the wildcards. To reverse, leave the option W.
%> zmv '(*).tex' '$1.txt' %> ls *.txt bp_ccc.txt bp_xxx.txt bp_yxc.txt bp_yyy.txt
Now, we want to rename 'bp' to 'internshipreport' and leave the rest untouched :
%> zmv 'bp(*)' 'Internshipreport$1' %> ls *.txt Internshipreport_ccc.txt Internshipreport_xxx.txt Internshipreport_yxc.txt Internshipreport_yyy.txt
A useful example is removing blank spaces from filenames :
%> ls -1 *.mp3 01 - Track 1.mp3 02 - Track 2.mp3 ... %> zmv '* *' '$f:gs/ /_' %>ls -1 *.mp3 01_-_Track__1.mp3 02_-_Track__2.mp3
You can find help to zmv in the man page "zshcontrib".
Turning off getopt
Sometimes it is necessary to turn off the internal getopt parser. For example if you try to rename files with weird names. The option "--" turns getopt off, for the arguments that follow. Example:
#> ls -testfile #> rm '-testfile' rm: illegal option -- t #> rm "\-testfile" rm: \-testfile: No such file or directory #> echo "Getting desperate..." #> rm -- -testfile #> echo "Voila, Thank you astro ;)"
Another solution (from KDE Women Homepage - "Linux-in-a-console" tips):
#> rm ./-testfile
Use vim-like less
'less' and 'more' are very basic. They do not know syntax highlighting. 'vim' can colorize almost every filetype. With following alias, you can use vim as an "extended less".
alias eless='/usr/pkg/share/vim/vim64/macros/less.sh'
When called as 'eless', vim now can be used like less (h for help). The vim commands remain functional.
Vim with Line Numbering and Syntax Highlighting
To have line and row numbers in vim just add following to your .vimrc (also works for NetBSD's vi, nvi):
set ruler
For Syntax Highlighting add:
syntax on
When using gvim, the font can be changed permanently using:
set gfn=Monospace\ 14
Replace the font with your preferred choice, of course.
Unlimited undo in nvi
A little-known secret is that our vi(1) (which is actually the same as editors/nvi) also has unlimited undo, even though many people say this is their biggest problem with nvi as opposed to vim.
Just press u to undo, then use . (dot) to repeat the operation. If you want to change the direction of undo ("redo" or ^R in vim), use u again.
Easy kernel config file editing
Kernel configuration files, shellscripts, Makefiles and others use a hash symbol (#) to denote a comment. Since editing the GENERIC kernel config is so much work to go through and often you don't need whole blocks of drivers (eg, pcmcia drivers on a desktop station), you want to be able to just go to the start of the block, press one key and have the whole block (until the next empty line) commented out. To do this, stick the following in ~/.exrc for nvi:
map * :/./;/^$/-1s/^/#/^Mj map \xb8 :/./;/^$/-1s/^#//^Mj
The \xb8 is actually alt+8. Enter the ^M (newline) as a literal by pressing ^V first, followed by ^M. Now you can comment out a block from the cursor to the end with * (Shift+8) and uncomment one with Alt+8.
vi tutorial
For more vi sweetness, there is a very good tutorial to vi available in the nvi source tree.
Get a list of all non-system users
This command show all users which have an UID >= 1000. You can change this value depending of your configuration.
$ column -ts ':' /etc/passwd |awk '{ if($3 >= 1000 || !$3) print $1 }'
How to get the external IP
Yet another external IP detector :-)
$ wget checkip.dyndns.org -qO ipaddr && cat ipaddr |cut -d '/' -f 3 |rev |awk '{print $1}' |colrm 1 1|rev ; rm ipaddr
Same thing, but without the temporary file on Linux
$ wget checkip.dyndns.org -qO /dev/stdout |cut -d '/' -f 3 |rev |awk '{print $1}' |colrm 1 1|rev
Same thing, although with all native NetBSD tools and no temporary file :o)
$ ftp -aVo - http://checkip.dyndns.org | cut -d '/' -f 3 | rev | awk '{print $1}' | colrm 1 1 | rev
Get the "original" filename from a binary file
This (useless?) command has been written for funny.
$ strings -a `which pwd` | sed -n '/_ctors_aux/,/[^c]$/p' |tail -2 |head -1 pwd.c
Remove all pkgsrc packages
This command works to remove all installed packages:
$ pkg_delete "*"
Including the * in quotes is necessary to avoid filename expansion.
- hubertf once once suggested this one :
$ pkg_delete -r -R \*
Create GUI applications from the shell
X applications can be written from the shell using the arshell utility of the AntiRight project.
The following is a panel showing vmstat statistics, updated every five seconds:
$ arshell -Uf 5000 -UL 'vmstat' -xrm '*fontList: fixed' &
The following is an X Dashboard, displaying system statistics (customize to suite your system's configuration):
#!/bin/sh
arshell -Uf 3000 -Ac\
-xrm '*overrideRedirect: True'\
-xrm '*background: black'\
-xrm '*foreground: red3'\
-xrm '*fontList: -*-lucidatypewriter-*-*-*-*-12-*-*-*-*-*-*-*'\
-UL 'tail -n 4 /var/log/messages'\
-UL 'tail -n 4 /var/log/ipmon'\
-UL 'tail -n 4 /var/log/ppplog'\
-UL 'pppstats'\
-geometry 1600x320+0+0 1> /dev/null 2> /dev/null
Any non-option argument passed to arshell is interpreted as a button definition, which is simply a command to execute on pressing the button. The last word of the button command definition is used as the label, with underscores translated into spaces. So, a useful way to provide descriptive labels for commands is to append the label after a comment character ('#'), if it is not part of the command itself.
Quick updating of IPF firewall rules
When making changes to the IPF firewall, the ipfilter and ipnat services must be restarted. Here is an alias to do this quickly:
$ alias uip="/etc/rc.d/ipfilter restart; /etc/rc.d/ipnat restart"
Updating dyndns information using wget
Here is a shell script to update your dynamic DNS address. It is useful to include this information in your ip-up script if you use ppp for internet access. The url syntax information was provided on the www.dyndns.com site.
#!/bin/sh # # Parameters: # 1 = Username # 2 = Password # 3 = Hostname # 4 = IP Address # if [ "$1" = "-h" ]; then echo Usage: echo ddns.sh uname psswd hostname ip exit fi wget "http://$1:$2@members.dyndns.org/nic/update?system=dyndns&hostname=$3&myip=$4&wildcard=OFF&offline=NO" -O -
Downloading an entire site using wget
Sometimes you want to download a complete book or something.
wget -r -k -p -nH --follow-ftp -np http://example.com
This will include images and such, not just the HTML. It will also adjust links to internal pages so they will refer to the local copy instead of to the server you got it from. It will also fetch (all) linked FTP files.
Load SSH agent within subshell
When you run ssh-agent, it prints out what you need to do in order to make SSH pick it up. To do this automatically, use the following alias:
alias agent='exec ssh-agent ${SHELL} -c "ssh-add; ${SHELL}"'
Now you can simply type
$ agent
and it will prompt for your keyphrases and in the new shell you can use SSH without exporting a lot of environment variables by hand. The shell will be replaced by a shell which has these settings in the environment.
Alternatively, if you want to add or replace the SSH_AGENT_PID and SSH_AUTH_SOCK variables in your current shell, you can define the following alias instead:
alias agent='eval `ssh-agent`; ssh-add'
Check MD5 sums
The "md5" command in NetBSD 3.0 does not support the "-c" option for automatically checking MD5 sums. The following script will allow you to automatically check MD5 sums.
#!/bin/sh
MSG="No error(s) encountered! Yay!"
while read line; do
PTHCHK=`echo "$line" | sed -e 's/MD5\ (//; s/)\ =\ \([0-9a-f]\{32\}\)$/:\1/'`
MD5PATHNAME=${PTHCHK%%:*}
MD5CHECKSUM=${PTHCHK##*:}
if [ -f "$MD5PATHNAME" ]; then
F=`md5 "$MD5PATHNAME" | sed -e 's/MD5\ (//; s/)\ =\ \([0-9a-f]\{32\}\)$/:\1/'`
CHECKSUM=${F##*:}
if [ "$MD5CHECKSUM" = "$CHECKSUM" ]; then
echo "$MD5CHECKSUM = $CHECKSUM ($MD5PATHNAME) -- ok!"
else
echo "$MD5CHECKSUM != $CHECKSUM ($MD5PATHNAME) -- error!"
MSG="ERRORS ENCOUNTERED!! Oh, noo!"
fi
else
echo "File not found: $MD5PATHNAME"
MSG="ERRORS ENCOUNTERED!! Oh, noo!"
fi
done <$1
echo $MSG
Micro-pause
This command plays, every 10 minutes, 5 beeps (separated by 1 second) using the system bell.
while true ; do sleep 600 ; for i in $(seq 1 5) ; do \ printf '\a' ; sleep 1 ; done ; done
The goal is to remember of do some periodic micro-pause in order to loosen the muscular tension. A real software for this kind of activity is Workrave.
