1. 程式人生 > 其它 >shell 學習筆記(19)

shell 學習筆記(19)

宣告:轉載需署名出處,嚴禁用於商業用途!

1801.關於 nohup 後臺執行的問題:
    nohup就是拒絕hup訊號,沒什麼其他用途,
    如果是shopt -s huponexit的話,shell在退出的時候自己把自己所有的子程序都發一個hup訊號,
    然後就退出了,但是我還沒見過哪種發行版會啟用這個引數的。
    後臺就直接加個&就行了:sh 1.sh & ,退出終端並不會終端程式,sleep 9999 &,然後退出,然後再登入,看下是不是還在 
    除非你shopt -s huponexit 才會斷掉,預設是不會有這個的 ,其實可以直接在指令碼內部trap hup訊號,這樣和nohup就一樣了 
    shopt |grep hup看下,如果是off,就不用nohup
    用ping測試了不行,ping是需要tty的,ping自己會判斷,如果失去tty就退出
1802.sort的預設分隔符:blank
    sort預設就是[ t]:By default a blank is a space or a tab,blank是空白符,不是空格符,空格是space 
1803.lastb : 登入不成功使用者記錄
1804.lsof監控程序或者程式
    lsof -i:22 //知道22埠現在執行什麼程式
    lsof -c abc //顯示abc程序現在開啟的檔案
    lsof -p 12  //看程序號為12的程序打開了哪些檔案
1805.設定 chattr 讓root無法修改:chattr +i file,lsattr file //檢視檔案屬性
1806.mkfs -t vfat /dev/hda6 :將移動硬盤裡面的一個分割槽格式化成vfat格式
1807.mount /dev/cdrom /media/cdrom  //掛載cdrom
1808.getent group 532 //通過組ID,來查詢組資訊
1809.linux的備份還原:
    dump -S /dev/sda2 //檢視一下要備份/dev/sda2所要的容量
    dump -0j -f /dev/hda2/sda2_bak.dump.bz2 /dev/sda2  //將sda2進行備份並壓縮
    restore -t -f /dev/hda2/sda2_bak.dump  //檢視備份資訊
    restore -r -f /dev/hda2/sda2_bak.dump  //還原備份
1810.linux新增、刪除網段路由:
    route del -net 172.168.0.0 netmask 255.255.0.0 dev eth0 //刪除 172.168這個網段
1811.nmap安全掃描:
    nmap -sP 172.30.4.0/24  //在這個網段內有多少使用者在我的主機上操作,一個不錯的安全檢查工具
1812./sbin/killall5 殺死除了核心執行緒和自己的session(當前shell)之外的所有程序(root會把當前shell也殺了),sysvinit-utils裡面帶的
1813.perl正則:環視 不匹配多個字元
    (?<=) (?=)    # 每組環視都成對出現,分為前視、後視
    (?<!) (?!)
    匹配到非行首的2013的正則:
    echo "20130331_ershouch_putong_post_phoneQuit 120130401_ershouch"|grep -P '(?<!^)2013'        # 繞一點的寫法:grep -P '(?!^2013)2013'
1814.檔名亂碼後,file -i 檢視編碼:
    ls|file -i - 
    /dev/stdin: text/plain; charset=utf-8
1815.linux 如何複製使用者資訊到另一臺機器
    1. 複製3個檔案:/etc/passwd,/etc/group,/etc/shadow
    2. 為各個使用者建立home目錄
    3.複製使用者home目錄下的.bashrc .bash_profile
1816.從世界標準時間中心獲取時間:
    ntpdate 0.pool.ntp.org
1817.alias只是在互動式shell下才有生效,因為其他環境不會執行profile和rc 
1818.關於cp覆蓋一個正在執行的檔案,遇到:cp: cannot create regular file `test': Text file busy
    其實這是新版本linux的一個特性,老版本沒這個問題,而且二進位制檔案沒問題,文字檔案有問題 
    當時一個指令碼,換到debian7上怎麼都不行,發現是flock的問題,新版本的flock,如果你flock一個指令碼,
    那麼這個指令碼就沒法執行了,二進位制檔案沒事。 我去官網找原始碼編譯了下,果然是這樣,應該在某個版本的時候改了策略 
1819.control + c 傳送 SIGINT 訊號的問題:
    如果你用kill指令而不帶任何引數,實際上是傳送了一個SIGKILL訊號。但是kill指令是可以傳送指定訊號的,
    比如你要發一個SIGINT訊號,可以這樣:kill -s SIGINT process_name
1820.awk -F 域分隔符轉義問題:
    echo 1[ab]2[ab]3[ab]4|awk -F'\[ab]' '{print $2}'    #注意單引號、斜槓問題,其實完整的後一個也要轉義的。
1821.convmv 轉換檔名編碼,其實這是一個 perl 指令碼:
    11:19:40#tp#test> echo 中國|iconv -f utf-8 -t gbk|xargs touch
    11:19:47#tp#test> ls
    ?й?
    11:21:32#tp#test> convmv -f gbk -t utf-8 * --notest
    Your Perl version has fleas #37757 #49830
1822.tail -f 和 grep 進行日誌的實時監控:# 其實tail -f用的就是inotify 
    tail -fn0 /var/log/php.log|grep --line-buffered error|while read line
    do
        echo $line|mail -s error [email protected]
    done 
1823.大量time-wait:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
    #vi /etc/sysctl.conf
    net.ipv4.tcp_tw_reuse = 1        #將TIME-WAIT sockets重用
    net.ipv4.tcp_tw_recycle = 1        #開啟TCP連線中TIME-WAIT sockets的快速回收
    # 注意 tcp_timestamps, tcp_tw_resycle 不要同時開啟
    # http://blog.sina.com.cn/s/blog_781b0c850100znjd.html   
    # http://www.litrin.net/2013/03/01/android%E4%B9%8B%E7%BD%91%E7%BB%9C%E4%B8%A2%E5%8C%85%E4%BA%8B%E4%BB%B6/
    #sysctl -p
1824.使用 LC_ALL=C 的意義:
    Linux中有關locale的設定會影響大量的命令列工具,其中包括排序工具。
    多數安裝的Linux系統都將LANG或者其他的locale預設設定成US English。
    但這可能會導致排序及其他命令慢上好幾倍。
    因此export LC_ALL=C 能避免使用i18n形式處理資料,帶來效能提升。
1825.瞭解sort的常用選項 (-t,-k, -s)如何工作:
    注意-k1,1只會排序第一列,而-k1會根據整個行排序。 -s能實現穩定排序。
    例如,先使用第二個域排序,再按照域一排序,可以用這段命令實現
    cat INPUT_FILE | sort -k1,1  | sort -s -k2,2
    echo "
    2 1
    1 1"|sort -sk2,2
    這個只是在 col2 有相同值的時候,保持其它列的順序維持不變
1826.需要輸入製表符,可以使用 Ctrl-V <tab> 或者 Ctrl-V-I 或者  $'t'
1827.kill -3 <pid>:SIGQUIT
    在除錯Java程式時,使用此命令,可以在stderr/logs中找到完整的stack trace,堆資訊(包含垃圾收集的細節).
1828.curl 設定超時時間,並獲取返回碼:
    curl -m9 g.cn/a.gif -so a.gif -w '%{http_code}n'
1829.curl FTP 下載檔案:
    curl -T "{file1,file2}" http://www.uploadtothissite.com 或者這個也是支援的,man curl裡面有
    -X PUT 就是 -T ,--ftp-method 指定ftp方式,比如get還是put
1830.ls -A和-a的區別是-A不顯示.和.. 
1831.一些配置檔案的路徑區別:
    profile是login shell,rc是non-login shell,etc下面是共用的,自己目錄下面是使用者自己的。
1832.通過 secure CRT 的 sftp 協議上傳下載檔案:
    與遠端LINUX伺服器交換資料。一般情況下通過以下幾種。
    1、是通過NFS通過MOUNT來掛接遠端WINDOWS共享的網路檔案系統CFIS進行資料交換。
    2、通過HTTP單方面交換資料。
    3、通過FTP來交換資料。
    4、通過SFTP使用SSH交換資料,這個功能利用了Secure CRT和SSH的功能來實現,非常簡單也需要中轉伺服器。
    sftp> lcd C:/Users/june/Desktop
    sftp> lpwd
    C:/Users/june/Desktop
    sftp> get part-r-00000
1833.在linux下如何將中文目錄壓縮成中文壓縮包
    rar和7z可以儲存編碼,其他都不行,zip、tar打包的要在同一作業系統解壓,否則是亂碼。 
    unix用tar打包的檔案,在windows下解壓是亂碼,因為當時unix下是utf-8的,然後windows下是gbk的,
    所以如果你把U盤拿回linux上,用utf-8掛載,又是中文了。
    要看掛載的時候的編碼,如果都是gbk的話,是一樣的。現在對於fat和nfts,預設就是用gbk編碼掛載的 
    當然,windows是沒法選擇掛載的時候的字元編碼的,檔案編碼和掛載的時候的編碼沒關係的 
    linux 可以選擇掛載編碼:mount後面有引數的,iocharset 
1834.rsync 的 --exclude 排除檔案/資料夾用法:
    --exclude=/dir 只排除 /dir
    --exclude=dir 排除/dir abc/dir a/dir
    /data/dir
    /data/abc/dir
    如果你用--exclude=dir,那麼上面兩個都被排除了,
    其實相對路徑就是通配所有的路徑,絕對路徑只排除一個
    --exclude-from=FILE是你要exclude的所有東西都寫在FILE這個檔案裡面,每個一行
    10:35:22#tp#test> find
    .
    ./d
    ./s
    ./s/a
    ./s/b
    ./s/b/a
    10:35:46#tp#test> rsync -nav --exclude=a s/ d/
    sending incremental file list
    ./
    b/
    10:35:59#tp#test> rsync -nav --exclude=/a s/ d/
    sending incremental file list
    ./
    b/
    b/a/
1835.關於 awk 的 block 快取問題:
    iostat 1|awk '{print $1;fflush()}' >a
    grep也有,--line-buffered可以按行來緩衝,而不是按block來緩衝,
    這樣可以馬上看到結果,但是資料量大的時候效能會很差,例如:
    while sleep .5;do echo $((i++));done|grep .|cat
1836.在指定時間執行 top 批處理模式獲取系統狀態資訊:
    at -f <(TERM=linux top -b -n 1 >/tmp/top-report.txt) now+1minutes
    top -p 4360,4358    # 監控指定程序
    top -U johndoe        # ‘U’為 真實/有效/儲存/檔案系統使用者名稱。
    top -u 500            # ‘u’為有效使用者標識
    Top 遍歷 /proc 資料夾,以收集程序資訊:strace -o /tmp/trace.txt top -b -n 1
1837.在當前資料夾下啟動一個內建的 php webServer,類似 python -mSimpleHTTPServer,PHP 5.4.0+
    php -S 127.0.0.1 8080 -t /dir
1838.殺死登入使用者的所有程序:
    pkill -u abc    # -t pts/n 終端
    -u 是effective user ID,-U 是real user ID
    pkill python -t pts/1 
    注意 pkill 一般要加 -x,否則它會模糊匹配,比如 pkill mysql,它會把 mysqld 也幹掉了。
1839.sed c 命令替換問題:
    sed '/AA/{cCC}' example.txt    # sed: -e 表示式 #1, 字元 0: 未匹配的“{”
    解決方法有2個:
    1.分成兩行寫:c換行CC換行}
    2.使用-e引數:sed -e '/AA/{cCC' -e '}' 
    如果你把它寫成一行,c命令會把後面的內容都當成要替換的內容,包括大括號,所以會報錯。
1840.linux下ps -fe和ps aux都是截斷,除非加-w,
    我螢幕寬度157個字元,就是157截斷,除非-ww,這樣才是完整的 
    13:19:50#tp#~> echo $COLUMNS
    157
    13:19:53#tp#~> ps -fe|wc -L
    157
    13:19:58#tp#~> ps -few|wc -L
    157
    13:20:00#tp#~> ps -feww|wc -L
    768
    13:20:02#tp#~>
1841.readlink 獲取腳本當前的絕對執行路徑:
    readlink /proc/7686/fd/255
1842.uniq 去重跳過 n 個字元/欄位的用法:
    echo "hi Linux
    hi LinuxU
    hi LinuxUnix
    hi Unix"|uniq -c -w 8        # -w 只比較前 n 個字元
    3 hi Linux
    1 hi Unix
    
    echo "aabb
    xxbb
    bbc
    bbd"|uniq -D -s 2         # -s 不比較前 n 個字元
    aabb
    xxbb
    
    echo "hi hello Linux
    hi friend Linux
    hi hello LinuxUnix"|uniq -D -f 2         # -f 不比較前 n 個欄位,-d 列印重複行一次,-D 列印所有重複行
    hi hello Linux
    hi friend Linux
1843.bash解析命令列引數,一般用 getopt 或者 getopts,getopts內建,但是不支援長引數 
1844.關於 ps -ef|grep [s]sh 可以排除自身的解釋:
    1、管道是非同步執行的:在執行ps的時候, grep也已經被執行, 不存在ps先執行後再把結果管道給grep的說法.
        因此 ps -ef|grep ssh 可能會有兩條/一條結果(ssh程序存在的情況下)
    2、其次在PS的結果中, grep行是 [s]sh, 而grep過濾的內容是ssh, 所以就不會命中grep自己.
1845.rsync 的幾個同步問題:
    最好別加 -u :否則如果回滾的話,不會同步,比如今天發了一個檔案,結果有問題,回滾到昨天,用rsync,他不會更新遠端的檔案
                    因為那個檔案沒目的地的新,所以因為-u引數,跳過,不會同步
    rsync 比較檔案,決定需要傳輸,預設採用 quick check 模式(size+timestamp),而不是 checksum,這樣省 IO
    timestamp 可以通過 --modify-window 修改,防止兩端的時間差帶來的影響
    -I, --ignore-times,是關閉 quick check 條件,每次全量同步,而不是增量同步,這樣 rsync 沒有優勢,不如 scp,可以省掉 服務端 IO
    --size-only、-c, --checksum 都是修改 quick check 條件,前者僅檢查大小,後者用 MD5 校驗和判斷檔案是否變化
    可以服務端禁掉一些浪費 IO 的選項:/usr/share/doc/rsync/examples/rsyncd.conf
    refuse options = checksum dry-run   # debian的rsync預設配置 
1846.nc 的妙用:
    nc 遠端傳輸檔案:
    nc -lp 1235 <a.log        # centos的話要注意,用-l,不是-lp,然後和redhat、debian、官方,引數都不一樣 
    nc 1.1.1.1 1235 >a.log 
    nc -l -p 3003 -e /bin/bash
    nc 中一行 Bash 指令碼建立並啟動 Web Server:# 不過還是 pythom -m SimpleHTTPServer 好用
    while true; do { echo -e 'HTTP/1.1 200 OKrn'; cat index.html; } | nc -l 8080; done
    netcat可以一行模擬遠端bash服務:
    netcat -lp 8888 -e /bin/bash
1847.wget 全站下載/抓取:
    wget -mp -nv 可以模擬一部分,不過css和js裡面呼叫的不行。 
    還有域名白名單用-D指定 ,否則只抓當前域名的 
    curl -sLO http://product.yesky.com/mobilephone/list[1-347].html
    加個-L,list1的時候有跳轉
1848.read 讀入兩個變數:
    echo "a b"|(read x y;echo $x;echo $y)    # read x y <<<"a b"
1849.ps 找出命令的啟動時間:
    ps -eo pid,lstart,cmd
1850.利用 kill 處理 cpu 溫度過高的程序:
    面對 cpu 負載過高導致溫度過高的情況,直接把top裡面cpu使用率最高的kill -19,然後再 kill -18 回來
    18) SIGCONT     19) SIGSTOP     20) SIGTSTP
    18是繼續,後面兩個都是暫停,其實CTRL-Z就是19或者20訊號,具體可以自己trap以下,CTRL+C是2訊號 
    19 和 20 的差異,請見 man 7 signal 
1851.date 裡面時間的 + - 注意格式會影響結果/時區(最安全的寫法是不要帶符號,用自然語言即可):
    date -d'2013-07-01 09:52:33 +1 minutes'        # 這個+1被當成時區了 
    Mon, Jul 01, 2013  4:53:33 PM
    
    date -d'2013-07-01 09:52:33 1 minutes'         # 同樣 -1 也會有問題
    Mon, Jul 01, 2013  9:53:33 AM
    
    date -u --date='+2 minutes 13-07-01 09:52:33'    # 把 + - 時間放在最前面也行
    Mon Jul  1 09:54:33 UTC 2013
    
    date -u --date='13-07-01 09:52:33 +0 +2 minutes'    # 注意前面的 -u UTC時間,少了也會有問題
    Mon Jul  1 09:54:33 UTC 2013
    
    date -u --date='13-07-01 09:52:33 GMT +2 minutes'    # 指定時區
    Mon Jul  1 09:54:33 UTC 2013
1852.gsub 去除單引號分割字串:
     echo "1,2,3,'e,f,g','a,b,c',2,"|awk -F"'" '{for(i=1;i<=NF;i+=2)gsub(","," ",$i)}1'
1853.shell 編碼規範:注意 [[ "x"$var == "x" ]], "x" 要放在前面,防止 -x 的出現
1854.巧用行號實現行內去重:
    echo "a b c a
    b c b"|awk '{for(i=1;i<=NF;i++){if(last[$i]!=NR)a[$i]++;last[$i]=NR}}END{for(i in a)print i,a[i]}'
1855.流量監控的話我覺得還是用iptables好,每天 iptables -vL 記錄流量,然後 iptables -Z 清空
    把埠和ip寫在iptables的acl裡面就, 可以按埠和ip監控,還可以指定協議或者連線狀態 
1856.平滑的切分 nginx 日誌:
    mv  tracklog.ooxx.com.access.log ${log_date_dir}/tracklog.ooxx.com.access.log.${log_name_date}
    kill -USR1 `cat /var/run/nginx.pid`
    mv xx.log date.xx.log,nginx會去寫date.xx.log,你reload,就寫xx.log了,fd沒釋放,程序會佔用這個檔案繼續寫
    如果 mv 後沒有 reload 就會有問題
    user1 reopen,這個訊號應該是nginx自己的,他的程式裡邊應該會捕獲這個訊號
    reload 是把子程序重啟了
1857.tree -d 列印目錄:
    tree -d|awk '{if(/-- 2013/){if(f==0)print;f=1}else{f=0;print}}'
1858.top -p 監視單個程序:
    top -p $(pgrep -d, nginx)
1859.tail -F 根據檔名而不是檔案描述符 FD 來監視檔案:
    比如 vim 編輯檔案 FD/inode 會變化:vim 預設類似 sed 不是 inplace,lsof|grep test.txt 可以看到原始檔被 deleted 了
    此時 tail -f 追蹤不到變化了,當然如果你 vim 中 se nowb(writebackup)的話不會改變 inode,vi -u NONE -N 也不會
1860.關於 .bashrc 環境變數在非登陸shell(nologin)環境下無法使用的問題:
    crontab 那種非登陸shell用不了 .bashrc 裡的設定,需要 export,然後 source 讓環境變數重新載入。
    .profile 也一樣
1861.正反程序替換的用法:
    iconv -f utf-8 -t gbk < <(echo 中國) > >(xxd)
    上面這個和 echo 中國|iconv -f utf-8 -t gbk|xxd一樣的 
    其實 <() 、<() 都是管道,<() 用在比如這個命令裡面的變數你後面還要用到的時候
1862.sort 排序字串中的數字:
    echo "aa2
    aa1
    aa13
    aa12"|sort -k1.3 -n
    -k1.3 相當於 -k1.3 -k1.9 排序指定欄位中的指定範圍的字串,如果是檔名的話,還可以 ls -v 按版本號排序
1863.sort -m 中的歸併排序 MergeSort,注意歸併排序需要你參與歸併的檔案先有序:
    21:15:44#tp#~> seq 1 2 999999 >b
    21:15:49#tp#~> seq 0 2 999999 >a
    21:15:52#tp#~> time sort -m a b >/dev/null
    real    0m0.287s
    user    0m0.268s
    sys     0m0.016s
    21:15:55#tp#~> time cat a b|sort >/dev/null
    real    0m3.873s
    user    0m3.824s
    sys     0m0.040s
    21:16:05#tp#~> 
1864.du -b:-b是用位元組數,然後顯示真實使用了多少,而不是佔用了多少。試著比較 du -B1 
1865.關閉 centos 的 ipv6 功能:
    vi /etc/sysconfig/network    新增
    NETWORKING_IPV6=no
    IPV6INIT=no
    vi /etc/modprobe.conf    新增
    alias net-pf-10 off
    alias ipv6 off
1866.關閉 centos 的 iptables 防火牆:
    /etc/init.d/iptables status
    /etc/init.d/iptables stop
    永久關閉:
    chkconfig --level 35 iptables off
    或者 直接 iptables -F 刪掉所有規則
    也可以直接修改
    /etc/sysconfig/iptables
    新增一條
    -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
    #/sbin/iptables -I INPUT -p tcp –dport 80 -j ACCEPT
    #/sbin/iptables -I INPUT -p tcp –dport 22 -j ACCEPT
    #/etc/rc.d/init.d/iptables save
1867.curl 獲取 request、response 請求頭資訊:
    curl -svo /dev/null http://www.hao123.com/ # curl -I 獲取的是響應頭資訊
1868.bash 獲取當前正在執行指令碼的絕對路徑:
    echo "scriptPath1: "$(cd `dirname $0`; pwd)
    echo "scriptPath2: "$(dirname $(readlink -f $0))
1869.程序代換的本質:
    其實程序替換相當於用fd來替代一個檔案
    11:23:11#tp#~> echo <(pwd)
    /dev/fd/63
    11:26:37#tp#~> 
    pwd執行結果在/dev/fd/63裡面,然後你可以用cat /dev/fd/63這樣的方式實現和cat a一樣的操作。
1870.date 獲取指定日期對應一年中的周序號和一週中的日序號
    man date | grep '%[UVWw]'
       %G     year of ISO week number (see %V); normally useful only with %V
       %U     week number of year, with Sunday as first day of week (00..53)
       %V     ISO week number, with Monday as first day of week (01..53)
       %w     day of week (0..6); 0 is Sunday
       %W     week number of year, with Monday as first day of week (00..53)
    seq 1 10 | xargs -i date -d "2012-1-{} 0:0:1" +"%V,%U,%W,%w"
1871.巧用 shell/awk 解決算術題:
    學習 X 學 == 好好好
    seq 10 99 | awk '{print $1, $1*substr($1,1,1)}' | grep -P ' (d)11'
1872.find 命令順序與邏輯關係帶來的高危操作:
    find . -delete -name *.pyc         
    -delete 和 後面的 -name 是 and 的關係,而且最好 *.pyc 帶上雙引號,防止shell擴充套件後帶來的空格問題
1873.kill -9
    kill -9 1 會重啟
    一般-9殺不掉就兩種,一個程序狀態是D,磁碟io卡住了,一個是Z,已經是殭屍了,沒法死了。
    其實殭屍只是死亡的一箇中間過程,每個程序結束的時候都會經歷,不過一般很快,你根本看不到。
1874.linux 下檢視執行緒執行在哪個 CPU 上:
    ps -eo ruser,pid,ppid,lwp,psr,args -L|grep mysql-proxy
    檢視執行緒:
    ps -eLf|grep mysql-proxy    # ps axms,ps aux,pstree -p pid,top -Hp pid,cat /proc/pid/status
    其中:
    LWP -- 輕量級程序,即執行緒,這裡顯示的是 thread id。 
    NLWP -- 執行緒數,即 number of threads in process。 
1875.time 時間含義:
    real:代表實際花費的時間
    user::代表cpu花費在核心外的時間
    sys:代表cpu花費在核心以內的時間
    通過把sys和user時間加起來可以獲得cpu在你的程式上花費的時間。
    如果sys和user加起來的時間比real時間要小很多,那麼你可以猜想你的程式的大部分效能瓶頸應該是IO等待的問題。
    Note that this is across all CPUs, so if the process has multiple threads it could potentially 
    exceed the wall clock time reported by Real. 所以多核多執行緒有可能 real < user + sys
1876.LC_ALL=C 的含義:
    Linux中有關locale的設定會影響大量的命令列工具,其中包括排序工具。
    多數安裝的Linux系統都將LANG或者其他的locale預設設定成US English。
    但這可能會導致排序及其他命令慢上好幾倍。
    因此export LCALL=C能避免使用i18n形式處理資料,帶來效能提升。
1877.關於 test -n:[ -n ] 的問題:
    -n要帶引數才是選項,否則相當於 [ "-n" ], 加了雙引號就是 [ -n "" ]這個時候-n是引數了
    igi@macbook:~ $ [ ] && echo 'yes'
    igi@macbook:~ $ [ xxx ] && echo 'yes'
    yes
1878.關於 2>&1 和 2&>1 的含義:
    2>&1和2&>1都可以的,就是格式,其實&沒意義,不一定在>後面。
    其實最好還是寫&>,因為有&>>這種寫法,但是>>&是不對的。
    >&和&>是一個組合,&不是和1或者2組合在一起的,2 >& 1 如果你攜程2 > &1會報錯的,2後面的空格去掉。
1879.printf 與 awk/sed 位數補全、千分位分割符:
    printf "%18sn" `echo 123456789.12 | sed '{:a;s/(.*[0-9])([0-9]{3})/1,2/;ta}'`
    echo '123456789.12'|awk '{printf "%'"'"'18.2fn",$0}'    # "%