標籤:shell linux 問題 匯總
Shell細小問題匯總
本文原文出處: http://blog.csdn.net/bluishglc/article/details/44276607 嚴禁任何形式的轉載,否則將委託CSDN官方維護權益!
- Shell細小問題匯總
- if 多條件組合判斷樣本
- Linux系統時間設定
- 在遠程節點上推送命令時需要特別注意和
- sudo -i和su -l的差異分析
- 關於 varrun和pid
- 檔案測試參數匯總
- 字串測試參數匯總
- 如何正確傳遞數組參數
- 批量修改檔案名稱
- 配置163 yum repo的指令碼
- 關於devnull 21devnull
- 標準輸入輸出和錯誤
- 的字串操作
- 的字串操作樣本
- 後台運行nohup
- 條件測試test
- 條件測試
- 預定義的變數
if 多條件組合判斷樣本
if [ ! "$STARTUP_TARGET" = "all" -a ! "$STARTUP_TARGET" = "hadoop" -a ! "$STARTUP_TARGET" = "spark" ]then echo "STARTUP_TARGET is invalid or not specified!" exit 1fi
注意:對於if來說,後面緊跟的“[”實際上是test命令的別名!所以後續的運算式都是test命令的參數,所以才會需要:
- “[“右側要加一個空格再跟參數
- “=”兩側都需要有空格
否則參數就連在了一起,變成了一個參數!
Linux系統時間設定
- 修改時區
很多系統在安裝時沒有設定時區,這樣很多系統預設就會使用統一協調時UTC來顯示時間,使用date來查看一下輸出時間就知道時區和時間是否正確了(如果是UTC表示是統一協調時,非本地時區,如果是CST表示中國標準時間,意味著時區已經正常)。通常,時間不正確多是只因為時區問題導致的,所以我們只需修改系統的時區就可以了,方法是把本地(中國上海)的時區檔案覆蓋到/etc/localtime即可:
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2.修改ls -l的時間格式
vim /etc/profile.d/time_style.shaddexport TIME_STYLE="+%F %T"
在遠程節點上推送命令時需要特別注意$!和$?
ssh -T [email protected]<<EOF su -l hive -c "nohup $HIVE_HOME/bin/hive --service metastore -hiveconf hive.log.file=hive-metastore.log -hiveconf hive.log.dir=$HIVE_LOG_DIR>$HIVE_LOG_DIR/hive-metastore.out 2>$HIVE_LOG_DIR/hive-metastore.log &" su -l hive -c "echo $!|cat>$HIVE_PID_DIR/hive-metastore.pid"EOF
上述指令碼中$!
的值永遠是當前主機或者說是本地shell下上一次背景程式的PID,而不可能是前一次推送的hive --service metastore
的PID!
sudo -i和su -l的差異分析
ssh -T [email protected]$NAME_NODE<<EOFsudo -i -u $HDFS_USER $HADOOP_HOME/bin/hdfs namenode -format -forceEOFsudo: sorry, you must have a tty to run sudo
此錯誤需要通過visudo來修改相關配置,若改為:
ssh -T [email protected]$NAME_NODE<<EOFsu -l $HDFS_USER -c "$HADOOP_HOME/bin/hdfs namenode -format -force"EOF
則沒有問題,總結起來:su -l要比sudo -i方便好用!
補充:雖然使用 su很方便,不過缺點是,當我的主機是多人共管的環境時,如果大家都要使用 su 來切換成為 root 的身份,那麼每個人都得要知道 root 的口令,這樣口令太多人知道可能會流出去,很不妥當呢!怎辦?透過 sudo 來處理即可!相對於 su 需要瞭解新切換的使用者口令 (常常是需要 root 的口令), sudo 的運行則僅需要自己的口令即可! 甚至可以配置不需要口令即可運行 sudo 呢!
關於 /var/run和pid
Well since /var/run is mounted as tmpfs. That means it’s totally empty when your machine boots and it’s meant to be like this to prevent stuff like daemons not starting because of a left-over PID-file.
Startup scripts usually create the directories they need before using them. If you want to store a PID-file either put it in /var/run directly or create a directory before creating the PID-file. This is no place to store data that needs to remain there across reboots.
- /var/run是linux約定應用程式存放pid檔案的地方(現在大多數系統已經改為了/run,然後把/var/run改為軟串連指向了/run),這並非是一個特殊的檔案夾,linux也不會強制應用程式把PID放在這裡,只是說這是一個“約定的,預設的”存放PID檔案的位置!這個檔案夾唯一特殊的地方在於:在當前大多數的Linux系統下,它被掛載為了tmpfs分區,這意味:只要系統重啟,檔案夾內的所有資料都會清空
- 首先我們需要明白:PID檔案本身和Linux作業系統沒有必然關係,它的產生和使用都是應用程式自已來負責的!一般來說,規範的應用程式在啟動時會到指定的檔案夾下尋找自己的PID檔案,如果檔案存在說明程式正在運行中,就終止當前的啟動程式,並給出提示資訊!如果不存在,才繼續進行啟動。當程式關閉時,也會自己刪除PID檔案!當然,以上說的是“規範”的應用程式,有的程式並不一定按照這樣的規範操作,這就需要具體情況具體分析了。
檔案測試參數匯總
字串測試參數匯總
如何正確傳遞數組參數
#!/bin/sht(){ nodeList="$1" echo ${nodeList[*]}}a=(1 2 3)t ${a[*]}
輸出: 1
#!/bin/sht(){ nodeList="$1" echo ${nodeList[*]}}a=(1 2 3)t "${a[*]}"
輸出: 1 2 3
批量修改檔案名稱
比如:將/etc/yum.repos.d下的CentOS的yum repo檔案統一添加bak尾碼:
for i in $(ls CentOS-*); do mv $i $i.bak;done
配置163 yum repo的指令碼
cd /etc/yum.repos.dfor i in $(ls CentOS-*); do mv $i $i.bak;donewget http://mirrors.163.com/.help/CentOS6-Base-163.repo
關於”>/dev/null 2>&1”,”>&/dev/null”
id user >&/dev/nullif [$? != 0 ]thenuseradd -s /sbin/nologin $userfi
上面是一段判斷使用者是否存在,如果不存在就添加使用者的指令碼,其中>&/dev/null 等同於 >/dev/null 2>&1 而>/dev/null 2>&1又等同於1>/dev/null 2>&1,它們的意思是一樣的,即:將標準輸出(也就是代表標準輸出的檔案1)重新導向到/dev/null(即不列印標準輸出資訊),然後把標準錯誤輸出(也就是代表標準錯誤輸出的檔案2)合并(也就是&符號的含義)重新導向到標準輸出,這樣,最終達到的效果或者說是目地為:捨棄命令執行中輸出的所有資訊(不列印任何資訊)!
在POSIX shell中,命令的結果可以通過%>的形式來定義(其中%表示檔案描述符:1為標準輸出stdout、2為標準錯誤stderr)!系統預設%值是1,也就是1>,而1>可以簡寫為>,也就是預設為>。
>&/dev/null
這是對 >/dev/null 2>&1
的一個縮寫!
標準輸入、輸出和錯誤
當我們在shell中執行命令的時候,每個進程都和三個開啟的檔案相聯絡,並使用檔案描述符來引用這些檔案。由於檔案描述符不容易記憶, shell同時也給出了相應的檔案名稱。下面就是這些檔案描述符及它們通常所對應的檔案名稱:
檔案 |
檔案描述符 |
輸入檔案—標準輸入 |
0 |
輸出檔案—標準輸出 |
1 |
錯誤輸出檔案—標準錯誤 |
2 |
系統中實際上有12個檔案描述符,但是正如我們在上表中所看到的, 0、1、2是標準輸入、
輸出和錯誤。可以任意使用檔案描述符3到9。
${}的字串操作
${}的字串操作樣本
file=/dir1/dir2/dir3/my.file.txt
我們可以用${}分別替換獲得不同的值:
${file#*/}:拿掉第一條/及其左邊的字串:dir1/dir2/dir3/my.file.txt${file##*/}:拿掉最後一條/及其左邊的字串:my.file.txt${file#*.}:拿掉第一個. 及其左邊的字串:file.txt${file##*.}:拿掉最後一個. 及其左邊的字串:txt${file%/*}:拿掉最後條/及其右邊的字串:/dir1/dir2/dir3${file%%/*}:拿掉第一條/及其右邊的字串:(空值)${file%.*}:拿掉最後一個. 及其右邊的字串:/dir1/dir2/dir3/my.file${file%%.*}:拿掉第一個. 及其右邊的字串:/dir1/dir2/dir3/my${file:0:5}:提取最左邊的5個位元組:/dir1${file:5:5}:提取第5個位元組右邊的連續5個位元組:/dir2${file/dir/path}:將第一個dir替換為path:/path1/dir2/dir3/my.file.txt${file//dir/path}:將全部dir替換為path:/path1/path2/path3/my.file.txt
記憶的方法為:
#是去掉左邊(在鑒盤上#在$之左邊)%是去掉右邊(在鑒盤上%在$之右邊)單一符號是最小匹配﹔兩個符號是最大匹配
後台運行nohup…&
Unix/Linux下一般比如想讓某個程式在後台運行,很多都是使用& 在程式結尾來讓程式自動運行。比如我們要運行mysql在後台:
/usr/local/mysql/bin/mysqld_safe –user=mysql &
但是加入我們很多程式並不象mysqld一樣做成守護進程,可能我們的程式只是普通程式而已,一般這種程式使用& 結尾,但是如果終端關閉,那麼程式也會被關閉。但是為了能夠後台運行,那麼我們就可以使用nohup這個命令,比如我們有個test.php需要在後台運 行,並且希望在後台能夠定期運行,那麼就使用nohup:
nohup /root/test.php &
條件測試:test,[ ]
shell中的測試條件有三種:test,[ ]以及(( ))。其中test和[ ]是等價的,”[“實際上只是test命令的一個別名而已!這也是 [ 之後必須有空格的原因。因此將二者歸為一類討論。
[ ]
[ ]的測試對象有三種:
字串 ,如[ -z str ]
數字,如[ n1 -lt n2 ]
檔案,如[ -f filename ]
[ ]內的變數,最好用雙引號包括; 中括弧內的常量,最好用單引號或雙引號包括,例如
if [ -z ${var} ] #可能出錯 if [ -z "${var}" ] #最好改成這樣
-a(與)和-o(或):進行多重條件的複合測試,如
if [ -n "${var}" -a "${var}" -lt 100 ] #當變數被定義且其值小於100時
取反測試!:對測試條件取反
if [ ! "$?" -eq "0" ] #上一條命令傳回值不等於0
條件測試:(( ))
1.(( ))作測試條件用時其中可使用類C的數字測試條件,包括
< :小於> :大於<= :小於等於>= :大於等於== :等於!= :不等於
2.經測試,(( ))中不能用-a,-o以及!等複合測試
3.(( ))除用作數值測試之外,還可用於變數自增減,如(( var++ ))
預定義的變數
Shell細小問題匯總