GhaSShee


Shell


# PDF ~~~ $ wget --spider --force-html -r -l2 "vitalik.ca" 2>&1 | grep "https" > hoge.txt $ cat url-list.txt | while read line ; do /Applications/Chromium.app/*/*/Chromium --headless --print-to-pdf="$(echo $line | sed -e 's/https\:\/\/vitalik\.ca\/general\///' -e 's/\//-/g' -e 's/html/pdf/')" "$line" ; done ; ./page2pdf.sh ~~~ # Devices ## list Devices ~~~sh @ osx $ diskutil list @osx @ linux $ fdisk -l $ mount -l ~~~ # Network program | obsoleted by ------------|--------------- arp | ip neigh ifconfig | ip addr ipmaddr | ip maddr iptunnel | ip tunnel route | ip route nameif | ifrename mii-tool | ethtool ## ipconfig ~~~sh # ifconfig | grep flags ... lo0: flags=8049 mtu 16384 gif0: flags=8010 mtu 1280 en0: flags=8863 mtu 1500 ... ~~~ ## ifconfig ~~~sh # ipconfig getpacket lo0 # ipconfig getpacket gif0 # ipconfig getpacket en0 ... ## if en0 is connected some information is listed ~~~ ## nmap nmap searches the state how an IP address serves in the Internet or Local Network. ~~~ > /& proxychains &/ nmap -A -p 1-22 (TARGET'S IP) ~~~ 22/tcp open ssh hydra is said to be a brute force attacking tool. To prevent this you can ban the IPs which have attacked you, and before that you have to be sure that your ssh username is long enough to be unpredictable. ~~~sh > hydra -l (USER TO LOG IN AS) -x 4:10:aA 192.168.8.101 ssh ~~~ # nc (netcat) ~~~ On ‘server’ side: $ rm -f /tmp/f; mkfifo /tmp/f $ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f On ‘client’ side: $ nc host.example.com 1234 $ (shell prompt from host.example.com) By doing this, you create a fifo at /tmp/f and make nc listen at port 1234 of address 127.0.0.1 on ‘server’ side, when a ‘client’ establishes a connection successfully to that port, /bin/sh gets executed on ‘server’ side and the shell prompt is given to ‘client’ side. When connection is terminated, nc quits as well. Use -k if you want it keep listening, but if the command quits this option won't restart it or keep nc running. Also don't forget to remove the file descriptor once you don't need it anymore: $ rm -f /tmp/f ~~~ # bc ~~~sh echo {1..100}" +" 0 | bc # Add up all the numbers from 1 to 100 using a brace expansion trick. ~~~ # pgrep ~~~sh $ pgrep sshfs 740 $ kill 740 ~~~ # function arguments ~~~sh print_str() { echo "$1, $2 !" } print_str "Hello" "World" // Hello, World ! ~~~ e.g. function ~~~sh jstdate(){ LANG=ja_JP.UTF-8 date } engdate(){ LANG=en date } $ date // 2014年 9月 25日 木曜日 20:36:48 JST $ jstdate // 2014年 9月 25日 木曜日 20:36:52 JST $ engdate // Thu Sep 25 20:38:01 JST 2014 ~~~

# zcat zcat : cat zipped text # nkf ~~~sh $ cat 文字化け.txt | nkf -wLux -w : convert to UTF-8 -Lu : convert to LF ( UNIX 改行 code ) -x : 半角カナを全角にしない ~~~ ~~~sh $ cat utf8.txt | nkf -sLwx -s : convert to Shift-JIS -Lw : convert to (CRLF) ~~~ cf. iconv ~~~sh $ iconv -f SHIFT-JIS -t UTF-8 < inputFile > outputFile ~~~ # rev ~~~ $ cat hello.txt hello world ~~~ ~~~ rev < hello.txt dlrow olleh ~~~ `<` : 標準入力 # zcat # uniq uniq the same line into a line ~~~ $ cat file.txt _ hoge foo hoge hoge foo $ cat file.txt | uniq -c 1 _ 3 hoge 2 foo ~~~ # sed 's; ; ;' ~~~ $ cat /etc/shells | grep -v '#' /bin/bash /bin/csh /bin/ksh /bin/sh /bin/tcsh /bin/zsh $ cat /etc/shells | grep -v '#' | sed 's;.*/;;' bash csh ksh sh tcsh zsh ~~~ 変数の文字列を先頭大文字にしたり全て大文字/小文字にしたりするのに sed は使わない。 ~~~ $ os=linux; echo ${os^} Linux $ os=linux; echo ${os^^} LINUX $ os=LinuX; echo ${os,} linuX $ os=LinuX; echo ${os,,} linux $ os=LiNuX; echo ${os~~} lInUx $ os=Linux; echo ${os//inu/umi} Lumix ~~~ # `cat -n` : display line number # `df` : disk free - display free space of disk # 3 2 1 ~~~ VLIST='1 2 3' t=; for val in $VLIST; do t="$val $t"; done for val in $t do echo "$val" done ~~~

# `curl` * curl は標準出力となる * wget ファイルとして保存 ~~~sh curl localhost:4000 |grep someword ~~~

## HTTP request jq のインストール ~~~ curl localhost:8080/api/json | jq curl localhost:8080/api/json -o response // save output to a file curl localhost:8080/api/json -o // save output to a file with a default name curl localhost:8080/api/json -O -# // show ####### 100.0% curl -s localhost:8081/api/json // exclude err but not displayed curl -Ss localhost:8080 // -S : shows error ~~~ ## HEADER ~~~ curl -I localhost:8080/api/json // get HEADER only ~~~ ## DUMP ~~~ curl --trace curl --trace-ascii ~~~ ~~~ curl --trace-time ~~~ jenkins を使い認証サービスを curl で使うことができる # `find` ~~~ $ find [path] [condition] [action] ~~~ ~~~ -type filetype f : normal file c,d : directory l : linking file -print : display the full path of files ~~~ e.g. show the contents of files with name "hoge" ~~~ $ find ./ -type f -print | grep 'hoge' | xargs cat ~~~ # `xargs` 標準入力からコマンドラインを作成し、それを実行する

# `grep` ファイルから文字列を検索する。grep の後に検索したい文字列を指定する # `|` (pipe) e.g. ~~~ > ls // a a.c b b.c c c.c > mv $(ls | grep -v ".c") ../mybin/ > ls // a.c b.c c.c ~~~ `*.c` files removed with -v option

# rename e.g. ~~~ > ls enshu1.c enshu2.c > rename 's/enshu/ex/' ./* > ls ex1.c ex2.c ~~~

# call functions from a file - `return(exit) (0~255)` : finish the function call - `echo` : output strings to the shell e.g. ~~~ --a.sh--- #!/bin/sh . ./b.sh ## Load the file "b.sh" val=$(hoge) echo $? echo $val --b.sh--- #!/bin/sh hoge(){ echo "Hello, from hoge!" exit 251 } ~~~ ~~~ $ ./a.sh 251 Hello, from hoge! ~~~

# Shell ## shell classification - outer command : executable files - builtin command : defined and used only in the shell - alias - `type` : alias -> builtin -> outer の順に優先して表示 - `type -a` : 全部を表示
 - `which` : display only outer command e.g. ~~~ 

$ type set
 set is a shell builtin
 $ which set
 /usr/bin/which: no set in (/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/xxx/bin) #=> ~~~

# wait wait for bg process to exit ~~~ $ sleep 10 & $ wait [1]+ Done sleep 10 $ ~~~

# `-e` option 終了ステータスが0以外だった場合はただちにシェルを終了する ~~~ $ sh -e > true > false //終了ステータスが1 $ ~~~ シェル実行中一時的に無効化したい場合 ~~~ $ sh -e > set +e // -e option を無効化 > true > false // 終了しない > set -e > true > false $ ~~~

# env 1. 環境変数の一覧表示 2. 環境を指定して実行

# `set -- ` 位置parameter を設定 ~~~ $ cat s16.sh #!/bin/sh echo $1 $2 $3 $4 $5 set -- a b c d e echo $1 $2 $3 $4 $5 $ ./s16.sh 1 2 3 4 5 1 2 3 4 5 a b c d e $ ~~~ この機能は繰り返し構文で同じ処理を実施する場合に使われる。 繰り返し構文の最初の段階で毎回`set -- $(eval echo \$any_vars$i)` のようにして値を設定し、繰り返し構文の中では$1や$2で値にアクセスできる。 for 文に代入できる変数は1つしかないので、この仕組みを使うと 複数の変数を使用できるようになる。
# set (unset) - 組み込みシェル変数を表示する - 変数の一覧表示  unset 変数の削除 ~~~ $ set Apple_PubSub_Socket_Render=/tmp/launch-8mNEZ5/Render BASH=/bin/bash ... OPTERR=1 OPTIND=1 OSTYPE=darwin13.4.0 PATH='/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:$PATH:/usr/local/apache-maven-3.2.2/bin:' PIPESTATUS=([0]="0") PPID=36585 PROMPT_COMMAND='update_terminal_cwd; ' PS1='\h:\W \u\$ ' PS2='> ' PS4='+ ' ... ~~~

# `getopts`: builtin command e.g. ~~~ $ cat opt.sh #!/bin/sh while getopts cs:n:a:wVh?v opt // : は引数をとることを意味する do // 引数は $OPTARG に格納 case "$opt" in c) colordiff_mode=true ;; s) waitsec=$OPTARG ;; n) colorhistnum=$OPTARG ;; a) alert_mode=true alertcommand=$OPTARG ;; w) fitwindowwidth=false ;; V) header_mode=true ;; h|\?) echo "$usage_msg" 1>&2 exit 0 ;; v) echo "topless version $version" exit 0 ;; esac done shift $(($OPTIND - 1 )) // 引数の読み込み位置を初期化 ~~~ `OPTARG` has arguments

# declare : 環境変数の表示

# exit : シェルを終了

# exec : プロセスの置き換え - execve システムコールに相当し、 - 自身を置き換えて実行する為、シェルはそこで途切れる - ラッパースクリプトなどで、本来実行したいとしているソフトウェアを実行するときに使われる ~~~ ---s14.sh--- #!/bin/sh exec /usr/bin/printf "done\n" //新しいシェルへ移動 /usr/bin/printf "done2\n" //この行は実行されない ------------ $ ./s14.sh done ~~~

# `:` ~~~ $ echo $b // $ echo ${b:-B} // B (変数に情報は保存しない) $ echo $b // ---------------------- $ echo $b $ echo ${b:=B} // B (&& 変数に情報を格納) $ echo $b // B ~~~ ## `:` : scilently ~~~ > : ${a:=123} // first : deal errors without output, so do scilently ~~~ ## `${name:-value}` `if ($name is null) value else $name` ~~~ > name=hello > echo ${name:-world} hello > name= > echo ${name:-world} world ~~~ ## `${name:+value}` `if ($name is null) $name else value` ## `${name:=value}` `if ($name is null) name=value && $name else $name` ## `${name:start:length}` ~~~ ${name:start} ${name:start:length} ~~~ e.g. ~~~ > x=catsle > ${x:3:2} ( ) (@@) ( ) (@) () @@ O @ O @ O (@@@) ( ) (@@@@) ( ) ++ +------ ____ ____________________ ____________________ || |+-+ | | \@@@@@@@@@@@ | ___ ___ ___ ___ | | ___ ___ ___ ___ | /---------|| | | | \@@@@@@@@@@@@@_ | |_| |_| |_| |_| | | |_| |_| |_| |_| | + ======== +-+ | | | |__________________| |__________________| _|--/~\------/~\-+ |__________________| |__________________| |__________________| //// O========O_/ (O) (O) (O) (O) (O) (O) > ${x:0:3} hello hello ~~~

# cd ~~~java /* ** this is a part of ** the sourceCode of ** ** ** COMMAND "cd" in ash ** ** ** writing about updatepwd() ** **「移動可能か調査してから移動する」 ** を記述したソース */ static void updatepwd(char *dir) { hashcd(); //update command hash table if (prevdir) ckfree(prevdir); prevdir = curdir; curdir = dir ? savestr(dir) : null; setvar("PWD", surdir, VEXPORT); setvar("OLDPWD", prevdir, VEXPORT); } ~~~

# 展開 文字列展開の優先順位 1. チルダ展開 2. parameter 展開 3. コマンド置換 4. 算術演算 5. IFS (Input Field Separator) 6. パス名展開 7. クウォートの削除

## `*` `?` : パス名展開 ~~~sh $ l /usr/l*/lib* /usr/lib/libACSClient.dylib* /usr/lib/libecpg_compat.dylib@ ... ~~~ ? : 1 character ~~~sh $ ls ?.txt a.txt 5.txt ~~~

## "" : フィールドセパレータ分割 ~~~sh $ a=$(printf " a b\n c \n\t ") $ echo $a // 展開結果にはIFS変数の分割に従って展開 a b c $ echo "$a" // "" でくくると文字列として展開 a b c ~~~

## `%` `%%` / `#` `##` : parameter展開 - %と%%は右から削除 - #と##は左から削除 ~~~sh $ ENV=/home/sh/.shrc $ echo $ENV // /home/sh/.shrc $ echo ${ENV%e*} // /hom $ echo ${ENV%.*} // /home/sh/ $ echo ${ENV#*/} // home/sh/.shrc $ echo ${ENV##*/} // .shrc $ echo ${ENV%h*} // /home/sh/.s $ echo ${ENV%%h*} // / ~~~

## コマンド置換 $( ) で囲まれた文字が対象

## 算術展開   $(( ))   で囲まれた文字列が対象

## チルダ展開 | | | | ------------- | -------------------- | | ~ | $HOME を表す | | ? | 任意の一文字 | | * | 任意の文字列 | | [文字列] | 文字列内のどれか 1 文字 | | [^文字列] | 文字列内の文字以外の文字 |

## ブレース展開 (bash~) ~~~ $ touch {1..3}{0..9}番目の{書類,個人情報}.txt $ l 10番目の個人情報.txt 20番目の個人情報.txt 30番目の個人情報.txt 10番目の書類.txt 20番目の書類.txt 30番目の書類.txt 11番目の個人情報.txt 21番目の個人情報.txt 31番目の個人情報.txt 11番目の書類.txt 21番目の書類.txt 31番目の書類.txt …. ~~~

## cat << EOF ~~~ $ cat << EOF >a.txt >this is a pen >i am tom >EOF $ cat a.txt this is a pen i am tom ~~~

# operators - 単項演算子: ! , ~ , + , - - 二項演算子: * , / , %, +, -, <, >, <<, >>, <=, >=, ==, !=, &, ^, |, &&, || - 代入演算子: = , +=, -=, * =, /=, %=, <<=, >>=, &=, ^=, |=, - 条件演算 : ? , :

# special variable * $0 : 第0引数 つまりシェル名(コマンド) * $#:引数number * $* : * $@ * $? * $$

# `>` / `<` : output / input ~~~ 2>&1 :「 標準エラー出力 」を「 標準出力 」と同じ場所に出力 1>&2 :「 標準出力 」を「 標準エラー出力 」と同じ場所に出力 ~~~ copy of file descriptor ~~~sh 2>    : 2 is "descriptor number" > , 1> : descriptor number is 1 ~~~ e.g. ~~~sh $ awk '$1>>1' // output Syntax error awk: syntax error $ awk '$1>>1' 2> err $ cat err awk: syntax error ~~~

# read (builtin) ~~~sh $ cat data 1 2 3 4 5 6 7 8 9 ~~~ 最後にデータを入力する ~~~sh $ while read a > do > i=$(($i + $a)) > done < data      $ echo $i 45 ~~~ パイプで渡すと失敗する ~~~sh $ cat data | > while read a > i=0 > do > i=$i+1 > done ^C $ echo $i      //スコープ外なのでnull ~~~

# シェルとカーネル 通常のソフトは直接システムコールをたたくことはない シェルは直接システムコールを積極的にたたくソフトウェア シェルのソースコードを読むとその辺りがよくわかる ashまたはdashがとっかかりとしてはよい リダイレクト:シェルの入出力機能 ashの実装から: ~~~ //nodetypes (ファイルリダイレクト裏に関するリスト) NTO nfile # fd > fname NFROM nfile # fd < fname NFROMTO nfile # fd <> fname NAPPEND nfile # fd >> fname NCLOBBER nfile 1# fd >| fname NTOFD ndup # fd <& dupfd NFROMFD ndup # fd >& dupfd NHERE nhere # fd << \! NXHERE nhere # fd << ! ~~~ //redir.c (リダイレクトリを処理している部分) ~~~c case NTO: if (Cflag) { fname =redir->nfile.expfname; if(stat(fname, &sb) == -1){ if((f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0) error(""); } else if (!S_ISREG(sb.st_mode)){ if ((f = open(fname, 0_WRONTY, 0666)) < 0) error(""); if (fstat(f, &sb) != -1 && S_ISREG(sb.st_mode)) { close(f); error(""); } } else error(""); goto movefd; } ... movefd: if (f != fd) { if (dup2(f,fd) == -1) { e = errno; close(f); error(""); } close(f); } break; //例外処理を除いて書くと case NTO: f = open(fname, O_WRONTY, 0666); dup2(f,fd); close(f); ~~~

# shell declaration statement ~~~sh #!/bin/sh  ~~~

# null file pointer cleanup file ~~~sh /dev/null > filename ~~~ ~~~sh : > filename ~~~ でも削除できる e.g. abc.logを圧縮し、元ファイルを削除する ~~~sh #!/bin/sh cp -p abc.log abc.log.bak gzip abc.log.bak cat /dev/null > abc.log ~~~

# shells ~~~sh $ ls -il /bin/ | grep sh 11153 -r-xr-xr-x 1 root wheel 1228240 May 13 03:55 bash* 334486 -rwxr-xr-x 2 root wheel 357984 May 13 04:00 csh* 291606 -r-xr-xr-x 1 root wheel 1315248 May 13 04:00 ksh* 11154 -r-xr-xr-x 1 root wheel 1228304 May 13 03:55 sh* 334486 -rwxr-xr-x 2 root wheel 357984 May 13 04:00 tcsh* 335114 -rwxr-xr-x 1 root wheel 530320 May 13 04:00 zsh* ~~~ ## dash - dash : debian's default shell - ash : older one

## bash - ashにくらべ重いが - 「ブレース展開」という拡張機能がある ## ksh ksh だけの機能 ~~~ $ cat <<< inline_here_documents inline_here_documents ~~~

## csh switch文とfor文の記述の仕方が違う ~~~ sh # csh # set prompt = "" ~~~ ~~~ foreach i (0 1 2 3) echo smartctl -a /dev/ada$i end ~~~ ~~~ switch ("a") case "a" echo a breaksw case "b" echo b breaksw default: echo default breaksw endsw ~~~

## bourne shell (sh) - `~/.bashrc`にその他の設定を記述 - `~/.bash_profile`に基本設定と ~~~ sh if [ -f ~/.bashrc ]; then . ~/.bashrc fi ~~~ とし、ログイン時に.bashrcを読み込む ## chsh change shell command ~~~sh $ chsh Changing shell for … => editorが起動 ~~~

# mdls :メタデータを表示 ~~~sh $ mdls a.jpg //jpegのメタデータを表示 ~~~

# mdfind :メタデータの検索=Spotlight検索

# tee ~~~sh command|tee $ cal | tee cal.txt // カレンダーの出力結果をteeコマンドにわたし、teeによりファイルに書き出される ~~~

# locate   :指定した文字列を含むパスの検索 ~~~sh $ sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist  // データベース(defaultで毎週土曜午前3時15分に更新)の作成 $ sudo /usr/libexec/locate.updated  //手動更新 $ ls -lh /var/de/locate.database //データベースの場所 ~~~

# () : grouping :(括弧内はローカル変数として処理される) ~~~sh $ ( command ) $ echo 今年は$(date "+%Y")年です // 今年は2014年です ~~~

## variable = value ~~~sh $ osname = “Mac OS X” $ echo $osname // Mac OS X ~~~

## { }   :wrap variable Name ~~~sh $echo "${OS}OS X" MACOS X ~~~

## quotation ~~~ sh $ OS = MAC $ echo “$OS”  // MAC    $ echo '$OS'  // $OS  $ set `cal` $ echo $1 // September $ echo $2 // 2014 $ echo $@ // September 2014 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 ... $ echo $# // 39 => the # of args ~~~

## export VARIABLE :変数を環境変数にする(scope)

## `chmod` / `chown` / `chgrp` ~~~sh ls -l -rw-r-x— -rwxrwxrwx ~~~ ~~~ owner group other rwx rwx rwx 111 111 111 ←二進数  7 7 7 ~~~ ~~~ $ chmod 777 filename ~~~ -R : recursive : サブディレクトリ以下にも同様の処理を展開する ~~~ $ chmod -R 400 filename ~~~ ~~~ chown :オーナーを変更する chgrp :所有グループを変更する ~~~

## ACLs UNIX の conventional permission では - owner, - group, - other の三段階でしかアクセス制御できない ACLs : Access Control Lists ~~~ sh $ ls -l drwx———@ drwxrwxrwx@ drwxr-xr-x ~~~ 最後に@や+がついているとACLsが設定されている

# job & process job & process process is a elementary job sometimes consists of processes

## `ps` :プロセス一覧を表示

## `ctlr + z` :ジョブを一時停止

## `bg` :ジョブをバックグラウンドにする ~~~ sh $ bg %ジョブ番号 ~~~

## `fg` :フォアグラウンドジョブに切り替える ~~~ sh $ fg %ジョブ番号 ~~~ kill %jobNo. kill processNo.

# zsh ## short cut ~~~ Shortcut Action CTRL + A Move to the beginning of the line CTRL + E Move to the end of the line CTRL + _ Undo the last change CTRL + U clear the entire line CTRL + K Clear the char @cursor pos CTRL + W Delete the word in front of the cursor ESC + [backspace] Delete the word in front of the cursor ~~~ ~~~ ALT + D Delete the word after the cursor CTRL + R Search history CTRL + G Escape from search mode CTRL + L Clear CTRL + S Stop output to screen CTRL + Q Re-enable screen output CTRL + C Terminate/kill current foreground process CTRL + Z Suspend/stop current foreground process Command Action !! Execute last command in history !abc Execute last command in history beginning with abc !abc:p Print last command in history beginning with abc ~~~ ## Special setup for Mac OS X 1. Go to Terminal -> Preferences -> Settings -> Keyboard 2. To enable the use of the ALT or OPTION key, select use option as meta key 3. To enable the CTRL + [left arrow] and CTRL + [right arrow] shortcuts, select - control cursor left and set it to \033b and - control cursor right and set it to \033f. ~~~ CTRL + [left arrow] Move one word backward (on some systems this is ALT + B) CTRL + [right arrow] Move one word forward (on some systems this is ALT + F) ~~~