Hints and tips on bash
These are some helpful hints on various topics.
Search and replace in bash scripting
To get the value of variable X with all occurances of 'yy' replaced by 'zz' use the following expression:${X//yy/zz}
For example:
ORIG="foo to the bar"
REPLACED=${ORIG//bar/baz}
echo $REPLACED
The result is:
foo to the baz
Argument list too long, or how to use xargs
Suppose you want to remove all jpeg files from several directories. You userm -f `find . -name *.jpg -type f`and get "Argument list too long". What you have to do is to use xargs to automatically split the long list to several shorter and pass them to rm:
find . -name *.jpg -type f | xargs rm -fThis way several rm commands are executed, but your files are finally gone.
Creating files with fixed length and random content
Handy command to create file with fixed length and random content is dd. Some examples:File test1.bin, 10k size, containing only zero bytes:
dd bs=1024 count=10 if=/dev/zero of=test1.bin
File test2.bin, 100k size and random content:
dd bs=1024 count=100 if=/dev/random of=test2.bin
Above example is rather slow, especially for large files, so here's another way to generate pseudo-random file:
dd bs=1024 count=100 if=/dev/hda of=test2.bin skip=1000This will copy 100k from the hard drive 1М after the beginning.
Getting the last word of bash string
To get the last word of a bash string use awk '{print $NF}':echo "one two three" | awk '{print $NF}'
returns
three
One-liner for transfering SSH public key to remote host
cat ~/.ssh/id_rsa.pub | ssh hostname "cat >> ~/.ssh/authorized_keys"Rsync over ssh with non-default port
If you use rsync over ssh to a server running on port different from 22, for example 555, use the following format:rsync -a -e "ssh -p 555" rsyncuser@remoteserver:/data/to/sync /archive/
More on rsync
Prefix each output line with timestamp
Imagine the case: you were writing a program or a script that outputs some information in the console. Just when everything is almost complete you realize that you actually need timestamp on each message output. For example you need to know how long it takes to backup each of your users' home dirs. The solution is to go through all output commands and wrap them in a function that appends timestamps. Believe it or not, there's a lazier way to do this - it's a simple bash one-liner:> ./your_program | while read line; do stamp=`date`; echo "$stamp $line"; done
You can try it with
> du -sc /home | while read line; do stamp=`date`; echo "$stamp $line"; done
Iterating filenames with spaces in bash
Usually when you write some bash script and need to iterate through some files, you use constructions like those:
for file in /dir/*.c
do
echo $file
done
or
for file in `find /dir -name *.c`
do
echo $file
done
Both approaches fail when it comes to files with spaces, like "file with space.c". In this case you iterate over all three parts "file", "with" and "space.c" instead the file itself. To cope with this use:
find /dir -name *.c | while read file
do
echo $file
done
Add easily "sleep" functionality to your Linux box with installing zero new packages
If you want to be able to turn of your computer after a number of minutes you have a plenty of programs to choose from. Here's an easy way to do this with just using bash and at. Add the following to your .bashrc:
sleeper() {
echo 'init 0' | sudo at now + $1 minutes
}
The just use it - set you desktop to poweroff in 50 minutes:
> sleeper 50
Use pm-suspend or pm-hibernate instead of init 0 to suspend or hibernate.
Getting full directory path in bash and cmd prompt
To get the absolute path for the current or any other realtively addressed folder, for example the parent, use the following constructs:
bash
parent_dir=`cd .. && pwd`
cmd
set current_dir=%CD%
cd ..
set parent_dir=%CD%
cd %current_dir%
Recursively rename all files in a directory to another extension using bash
The following script renames all files in the current folder and its subfolders with extension .jad to .java
for file in `find . -type f -name *.jad`
do
mv $file `dirname $file`/`basename $file .jad`.java
done
Find files not owned by user
Here's how to find files in user foo home folder that are not owned by foo
find /home/foo ! -user foo
Find the jar that contains given Java class
If you have a folder containing several jars and you want to quickly find which one contains given class, use the following script:
findjar.sh:
dir=$1
class=$2
if [ $# -ne 2 ]
then
echo "Usage: `basename $0` <directory> <class>"
exit 1
fi
for file in `find $dir -name *.jar`
do
unzip -t $file | grep $class && echo $file
done
Example: find the jar containing MyClass in the folder /my/jars/folder:
findjar.sh /my/jars/folder MyClass