Shell (Command Line Interpreter)

GNU TOOLS

variables

args :

"$@"

From shell :

a=SHELL ; b=$(eval "echo \${${a}}" ); echo $b
/bin/bash

Same with makefiles :

a=SHELL ; b=$$(eval "echo \$${$${a}}" ); echo $$b

But it will fail if using gmake env

a=CURDIR ; b=$$(eval "echo \$${$${a}}" ); echo $$b
 export ${USER}_KEY=${EMAIL}
 t=${USER}_KEY
 VAL=$(eval echo \${t} )
 echo $VAL
 ps $(</var/run/exim4/exim.pid)

COREUTILS

expr --version # expr (GNU coreutils) 8.13

expr 0 + 1 && echo "ok as expected  [$?]" # 0
expr 1 + 0 && echo "ok as expected  [$?]" # 0
expr 0 + 0 || echo "ko unexpected [$?]" # 1

expr 0 || echo "ko unexpected [$?]" # 1 

http://www.gnu.org/software/coreutils/manual/coreutils.html#expr-invocation

     Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.
echo "i="{1,2,3}
i=1 i=2 i=3

@tag: WtF

Escape

mkdir -p $(dirname "${mypath}") 

will fail, use workaround :

dir=$(dirname "${mypath}") && mkdir -p "$dir"

Flow Control :

if:

if ! true ; then echo then ; else echo else ; fi # print : else
  t=1 ; if [ "$t" != "0" ] && [ "$t" != "" ] ;  then echo "zero" ; fi

for in :

export ARG=DllCanUnloadNow ; for f in *.lib  ;  do  echo "# $f:" ; dumpbin /symbols $f | grep $ARG ;  done

for using seq (or w/ bash (1..255) ):

p=192.168.0 ; for i in $(seq 1 255) ; do ping -c 1  $p.$i > /dev/null 2>&1 && echo "$p.$i" ; done

for () :

for (( i=0; $i <= 999 ; i++ )) ; do echo $i ; done

while : ( will eat one line each line)

cat $F | while l=`line` ; do  echo -E "$l" >> $F.tmp ; t=`line` ; done ; mv $F $F.orig ; mv $F.tmp $F

case :

  case "$m" in
      jan | Jan)
          m=01; ;;
          

UntiL :

          
until ping -w 1 -c 1 "$server" &>/dev/null ;do
  sleep 1
  n=$(( n+1 ))
  [ $n -eq 30 ] && break
done
          
          
#! /bin/bash
FILE=$1
# read $FILE using the file descriptors
exec 3<&0
exec 0<$FILE
while read line
do
	# use $line variable to process line
	echo $line
done
exec 0<&3

eval

    list='PWD USER'
    for key in ${list} ; do
        value=$(eval echo \$${key})
        echo "${key}=${value}"
    done

Line

ls | awk '{ system ($0 ) }' 
ls | while L=`line`; do     echo $L;         read t ;     exit;     done; # will not work 

Line per line : use IFS=$'\n'

prefix="date" ; IFS=$'\n' ; while [ 1 ] ; do date ; sleep 1 ; done | while read line ; do p="$(date +%Y%m%d%H%M%S)" &&  echo "$p: $prefix: $line" ; done
20131210122521: date: Tue Dec 10 12:25:21 CET 2013
20131210122522: date: Tue Dec 10 12:25:22 CET 2013

Pipe

ls /dontexist ; echo $? # = 2
ls /dontexist | tee log ; echo $? # = 0
ls /dontexist | tee log ; echo $PIPESTATUS # = 2

For Plain Sh or BusyBox

Workaound for '/bin/sh' or busybox

status=0
eval ` { ls /dontexists || echo status="$?"; } | tee /dev/null`
echo "# status=${status}"

Trace :

busybox sh ~/bin/test.sh 
+ status=0
+ ls /dontexists
+ tee /dev/null
ls: /dontexists: No such file or directory
+ echo status=1
+ eval status=1
+ status=1
+ echo # status=1
# status=1

@TaG: PipE

Multitask

#{
test_()
{
while [ 1 ]
do
echo "$*=$$"
sleep 1
done
}
main_()
{
test_ 1 &
test_ 2
}
$*
#}
/tmp/t.sh main_

Text manipulation

recurvive grep :

find ~/bin/ -type f  -exec grep -Hn  rzr {} \;

search & replace :

sed -e "s/rzr/RzR/g" < filein.txt >| fileout.txt
sed -e "s/rzr/RzR/g" -i fileinout.txt

pipes and `` :

#! /bin/sh
#file://~/bin/killall.sh
kill -9 `ps aux | grep $* | cut -b0-10`
killall.sh gdb

variables on sh bash

VARNAME=value
echo ${VARNAME}
export VARNAME #

variables on csh tcsh

set VARNAME value
echo $VARNAME
setenv VARNAME value

regex on Variables :

echo ${EMAIL}
# root@localhost
echo ${EMAIL/@/(a)}
# root(a)localhost

Variables

$ echo $RM
$ echo ${RM:=rm}
rm
$ echo $RM
rm
$ RM=delete.sh
$ echo ${RM:=rm}
delete.sh
$ echo $RM
delete.sh

stdout

printf "%c\n" $'\x31' # 1
decimal=49
eval printf \"%c\\n\" \$\'\\x$(printf "%02x" $decimal )\' # 1
eval printf \"%c\\n\" \$\'\\x$(echo "obase=16;$decimal" | bc)\' # 1
tar cf - $(find . -iname "*.h")  | tar xvf - -C  ${DESTDIR}/include

SED / [[AWK]]

find . -name "*,*" -type d -exec basename {} \; | awk '{ printf "mv " $1 " " ; sub (/_/,"-") ; print $1 }'
echo "9.999" | awk '{ printf "%.3f \n", $1 / 3 }'

remove each file

cat TODO | awk '{ system(" echo  " "rm -v \\\""  $1 "\\\" " ) }'

head -50 | tail -1 = sed '50q;d'

@more: AwK SeD sh

USEFULL BLACK MAGIC COMMANDS

Will rename C to C++ files name conventions

# ls *.c | xargs -n 1 --replace echo "mv {} {}pp"
mv mainc.c mainc.cpp
for i in *.ent; do	mv $i ${i/ent/gml} ; done
rename 's/\.ent$/.gml/' *
man mmv
grep -v "^$" # remove empty lines

prints executables :

find . -perm +100  -type f -exec file {} \; | grep "ELF 32-bit LSB"  | cut -d':' -f 1 

Copy all nodes :

s=/mnt/sdb6/
d=/mnt/sdb2/
cd "$s" && time tar cf - . | { cd "$d" && tar xfv - ; }

cat files.txt | awk '{  print "tar cvf - " $0 " | tar xvf - -C /tmp "}' > /tmp/movefiles.sh

COOL OPTIONS

ifconfig | grep -A1 "^eth" #                                                                                                                            
eth0      Link encap:Ethernet  HWaddr b8:70:??:??:??:??                                                                                                                                         
          UP BROADCAST MULTICAST  MTU:1500  Metric:1        

SCRIPT SHELL

A script shell is a simple series of shell commands : see :

# cat file.sh

#! /bin/sh
echo "I am a script shell"
date

# sh ./file.sh

I am a script shell
32 Dec 2000

search / replace with sed in multiple files :

for fl in *.*; do
mv $fl $fl.orig
sed 's/FINDSTRING/REPLACESTRING/g' $fl.orig > "$fl"
#rm -f $fl.orig
done
sed -i 's/gif/png/g' *.wrl

How to substract : 09 - 1 to return 08

totem  mms://vipmms.canalplus.fr/canalplus/zapping_`expr  $(date +%y%m%d) - 1`_a.wmv

PER HOST ENV

cat ../chhome/env-chhome.sh
#===/bin/sh===
# echo "+ file://~/env-chhome.sh"
t=${HOME}/etc/home/$HOSTNAME/$USER
# t=/home/$USER/etc/home/$HOSTNAME/$USER
[[ -d $t ]] && HOME=$t && export HOME
# file://~/.profile     : ok:console+login+bash
# file://~/.login       : ko:console+login+bash
# file://~/.xsession    : on [[Debian]]
# file://~/.xinitrc     :
# t=env-chhome.sh
# [[ -f $t ]] && source $t
# echo "- file://~/env-chhome.sh"

Joke

echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc 

MISC

TEXT

Here is the way to reverse “od” output :

  echo "test" | od -A x -t x1 | sed -e 's|^[0-f]* ?||g' | xxd -r
  test

DATA FLOW

BiN :

 while read -n 1 byte ; do printf "%b" "$byte" ; done < "$input" > "$output"

MISC

MorE

shell.txt · Last modified: 2019/01/14 12:21 by rzr
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki