User Tools

Site Tools


unix:unix

Unix stuff

The shortest fork bomb

In bash or tcsh:

  : () { : | : &};:

A better "ps auxww | grep"

To quickly find all the processes matching a pattern you can define an alias like:

alias jj='ps auxww | grep'

The side effect of this alias is that it often also matches the grep process. A better solution is to define a function like:

jj () {
  TAIL=${1#?}
  HEAD=${1%$TAIL}
  ps auxww | egrep $HEAD{1}$TAIL
}

The function is POSIX-compliant and works in bash and zsh.

Bridging in Linux

Let's say the interfaces you want to use for bridging are eth0 and eth2.

First of all remove the IP address from eth0 (if you have one) and activate all the needed interfaces:

ifconfig eth0 0.0.0.0
ifconfig eth0 up
ifconfig eth2 up

Now create the bridge, and connect to it the interfaces:

 brctl addbr br0
 brctl addif br0 eth0
 brctl addif br0 eth2
 ifconfig br0 up

Check that's everything OK, using

brctl show
brctl showmacs br0
dmesg

If you need IP connectivity for the bridge host assign an IP to br0:

dhclient br0

To remove the bridge, do:

brctl delif br0 eth0
brctl delif br0 eth2
ifconfig br0 down
brctl delbr br0

Managing files with spaces

If you have to work in the shell with a list of files with spaces in their names, coming from stdin, you can't (easily) use the «for f in *.blah ; do SOMETHING ; done» idiom. The quickest solution is to use the read(1) command:

ls | while read f
  do echo FOO $f
done

If using find and GNU tools, you can try something along the lines of:

find . -type f -name "*.blah" -print0 | xargs -0 -L1 echo FOO

When processing script parameters, use $@ (between double quotes) instead of $*:

for f in "$@"; do

Checksum with openssl

  • SHA1: openssl sha1 <filename>
  • MD5: openssl md5 <filename>

Find unlinked open files

With lsof, sorted by size:

lsof +L1  | sort -n -k 7
lsof +L1  | awk '{print $1,$3,$7,$10,$11}' | sort -n -k 3 | uniq

On linux, without lsof, try with

find /proc/*/fd -ls | grep  "(deleted)"

and, if it's a huge logfile you can lose, truncate it with :> /proc/xxxx/fd/yy

Memory map of a process

To show the memory map of a process (Linux, Solaris):

pmap -x PID

Posix ACLs

In Linux, Solaris you use getfacl(1) and setfacl(1).

For Mac Os X there are specific options for chmod(1).

Debugging a shell script

With set -x at the start of the script you enable the printing of the command as they are executed. Disable with set +x.

Surviving ksh (AIX / HP-UX)

stty intr ^C erase ^? kill ^U # HP-UX
set -o emacs
alias __A=$(print '\0020') # ^P = up = previous command
alias __B=$(print '\0016') # ^N = down = next command

In-place editing

perl -i.bak -pe 's/foo/bar/g' *.txt
ruby -i.bak -pe '$_.gsub!(/foo/,"bar")' *.txt
ruby -i.bak -pe '$_.gsub!(%r{/usr/},"/usr/local/")' *.txt # Without slashes
# Replace DOS EOLs in all *sh
sed -i 's/\r$//' *.sh
find . -name \*.sh -exec perl -i -pe 's/\r\n/\n/g' {} \;

Multiline string replace

ruby -e 'puts ARGF.read.gsub!(/pippo.*pappo/m,"pera")' < myfile.txt

Beware that in multiline mode:

  • ^ matches the start of the file, you'll probably need to use \n instead
  • probably the greedy behavior is too… greedy. Remember to use ?

Join lines starting with a RE

ruby -npe 'chomp! ; print "\n" unless $_.match(/^THISISMYREGEXP/); END {puts}'

Kill child processes on exit

#!/bin/bash
 
function killer()
{
  kill `jobs -p`
}
 
trap killer TERM INT
 
blah &
foo &
quux &
 
wait

rsync reminder

Remember that a trailing / in the source means “copy the content of this dir”

Linux

rsync --rsh=ssh --archive --verbose --acls --xattrs --one-file-system \
  --dry-run \
  --delete \
  /foo ap@host:/bar

…that's the same as:

rsync -e ssh -avAXxn --delete /foo ap@host:/bar

Mac Os X

rsync --rsh=ssh --archive --verbose --extended-attributes --one-file-system \
  --dry-run \
  --delete \
  /foo ap@host:/bar

Command history

To add command history and editing (readline-style) to commands (like wlst or sqlplus) you can use rlwrap as a wrapper.

rlwrap sqlplus

Bulk applying a sed command file

If for example you have a sed command file named placeholders.sed and you want to apply it to all the *sql files, you can run:

find . -name \*sql -exec sed -i -f placeholders.sed {} \;

For a search and replace, the sed command file could be something like:

s/&BIC_COUN/BR/g
s/&LOG_LEVE/6/g

Set operations from shell

cat a b | sort | uniq      # a union b
cat a b | sort | uniq -d   # a intersect b
cat a b b | sort | uniq -u # set difference a - b (lines in a not in b)

Each file shouldn't have duplicates, BTW!

Find the full execution path for a script

DIR="$( cd "$( dirname "$0" )" && pwd )"

sudo "sudoers" reminder

# Example
nagios    ALL=(ALL)  NOPASSWD: /sbin/service nrpe *
jboss     ALL=(ALL)  /etc/init.d/jboss*

Brace expansion

In shell, generate arbitrary strings by expanding a list. Example:

mkdir -p file/{send,rcv,tmp}
mv pippo{,.OLD}

SSL

Generate a SSL self-signed certificate

openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3650
cat key.pem cert.pem >> `hostname -f`.pem

Test SSL connection with client certificate

wget https://secure.example.com/ --ca-certificate myprivateCA.pem --certificate mycert.pem --private-key ./mykey.pem
openssl s_client -connect secure.example.com:443 -cert ./mycert.pem -key ./mykey.pem -CAfile ./myprivateCA.pem -state -quiet
openssl s_client -connect secure.example.com:443 -cert ./mycert.pem -key ./mykey.pem -CAfile ./myprivateCA.pem -msg -debug
curl -k --cert ./mycert.pem --key ./mykey.pem "https://secure.example.com/"

Port redirect with xinetd

Example: to redirect 8080 to 80 put in /etc/xinetd.d/tcpredirect-80-8080 (do not use dots in the filename) something like:

service tcpredirect-80-8080
{
 disable = no
 type = UNLISTED
 socket_type = stream
 protocol = tcp
 wait = no
 redirect = 127.0.0.1 8080
 #bind = 192.0.2.1
 port = 80
 user = nobody
}

Echo to standard error

To echo to stderr in bash:

>&2 echo "blah"
unix/unix.txt · Last modified: 2017/07/05 08:41 by ap

Informativa sui cookie