
在Linux上如果你想要多條命令一起運(yùn)行有幾種方式可以實(shí)現(xiàn)但具體使用哪種方式取決于你希望這兩條命令如何并行或順序執(zhí)行。1、順序執(zhí)行如果你希望第一條命令執(zhí)行完畢后再執(zhí)行第二條命令你可以簡(jiǎn)單地將它們寫在同一行用分號(hào);分隔。例如command1;command2這樣無(wú)論command1執(zhí)行成功還是失敗command2都會(huì)執(zhí)行。2、并行執(zhí)行如果你希望多條命令同時(shí)執(zhí)行互不干擾可以使用符號(hào)將第一條命令放在后臺(tái)執(zhí)行然后立即執(zhí)行第二條命令。但請(qǐng)注意這實(shí)際上并不是將多個(gè)命令“拼接”在一起執(zhí)行而是讓第一個(gè)命令在后臺(tái)運(yùn)行同時(shí)立即開始執(zhí)行第二個(gè)命令。例如command1command2但請(qǐng)注意由于只是將command1放入后臺(tái)如果command1的輸出很重要你可能需要重定向其輸出到文件或使用其他方式捕獲。3、使用和||進(jìn)行條件執(zhí)行僅當(dāng)?shù)谝粋€(gè)命令成功執(zhí)行即退出狀態(tài)為0時(shí)才執(zhí)行第二個(gè)命令。||僅當(dāng)?shù)谝粋€(gè)命令執(zhí)行失敗即退出狀態(tài)非0時(shí)才執(zhí)行第二個(gè)命令。例如command1command2# 如果command1成功則執(zhí)行command2command1||command2# 如果command1失敗則執(zhí)行command24、如果你在腳本里啟動(dòng)了后臺(tái)程序可以使用wait等待后臺(tái)進(jìn)程#!/bin/bash# 啟動(dòng)一個(gè)后臺(tái)進(jìn)程比如sleep 5sleep5# 獲取最后一個(gè)后臺(tái)進(jìn)程的PIDlast_pid$!# 輸出這個(gè)PIDecho最后一個(gè)后臺(tái)進(jìn)程的PID是:$last_pid# 等待這個(gè)特定的后臺(tái)進(jìn)程完成wait$last_pid# 輸出完成信息echo后臺(tái)進(jìn)程已完成5、管道上面的執(zhí)行方法中不難發(fā)現(xiàn)少一個(gè)|單獨(dú)寫在這里是因?yàn)樵趌inux中|是管道的意思也就是說嚴(yán)格規(guī)范的使用含義是把上一個(gè)命令的輸出作為下一個(gè)命令的輸入但是如果使用場(chǎng)景允許確實(shí)可以作為順序執(zhí)行的方法6、如果你要執(zhí)行的命令完全一致從而批量執(zhí)行命令可以使用 xargs 命令完成比如對(duì)所有機(jī)器發(fā)送一條命令#!/bin/bashLOCAL_FILE/path/to/local/fileREMOTE_DIR/path/to/remote/dirUSERyour_username# servers.txt 每行一個(gè)機(jī)器域名# 使用xargs并行執(zhí)行scp命令-P 10指定并行度為10 -I {} 這是個(gè)固定寫法用來(lái)代指拿到的數(shù)據(jù)后面的命令可以用 {} 占位符catservers.txt|xargs-P10-I{}scp-r${LOCAL_FILE}${USER}{}:${REMOTE_DIR}如果你要做的事情比較復(fù)雜需要一個(gè)代碼塊你可以導(dǎo)出一個(gè)方法get_presto_task(){localquery_id$1locallast_part${query_id##*_}localdata_position$((last_part%JOBS))curl-s$SERVER/v1/query/$query_id${OUTPUT_FILE}.${data_position}}export-fget_presto_task# xargs 命令是 sh 解析器所以要通過 bash -c 的方式顯示切回 bash$ 這是個(gè)固定寫法用來(lái)代指對(duì)后面的參數(shù)拆包 _ {} 這部分就是腳本參數(shù)列表 _ 是缺省寫法你也可以給本次bash進(jìn)程寫個(gè)具體名字{} 是管道拿到的內(nèi)容做第一個(gè)參數(shù)的意思cat$TMP_QUERYIDS|xargs-I{}-P$JOBSbash-cget_presto_task $ _{}多個(gè)命令同時(shí)執(zhí)行時(shí)往往會(huì)另行指定 bash 對(duì)錯(cuò)誤的處理方式也就是把下面的命令放在腳本的最上方# 定義腳本對(duì)執(zhí)行中出現(xiàn)錯(cuò)誤的處理方式# -e 任意命令返回非零狀態(tài)時(shí)立即終止腳本# -u 引用未定義變量時(shí)直接報(bào)錯(cuò)退出防止空值注入# -o pipefail 管道中任一命令失敗整個(gè)管道返回失敗狀態(tài)默認(rèn)只檢測(cè)最后一個(gè)命令set-euopipefail此時(shí)$?會(huì)失效因?yàn)橛龅藉e(cuò)誤腳本就退出了需要使用||邏輯# 方法1|| 短路邏輯set -e 不會(huì)終止curl-s$SERVER/v1/query/$query_id${OUTPUT_FILE}.${data_position}||{echo請(qǐng)求失敗:$query_id# 可以記錄日志、跳過、重試等}或者臨時(shí)告訴腳本這個(gè)命令可以失敗curl-s$SERVER/v1/query/$query_id${OUTPUT_FILE}.${data_position}||true還有一種寫法是將命令放在 if 中# 用 if 包裹if 條件中的命令失敗不會(huì)觸發(fā) set -eif!curl-s$SERVER/v1/query/$query_id${OUTPUT_FILE}.${data_position};thenecho請(qǐng)求失敗:$query_idfi# 簡(jiǎn)寫[[!curl-s$SERVER/v1/query/$query_id${OUTPUT_FILE}.${data_position}]] echo 請(qǐng)求失敗:$query_id