執(zhí)行shell腳本的各種方法小結
更新時間:2025年12月16日 10:54:14 作者:BullSmall
這篇文章主要介紹了執(zhí)行shell腳本的各種方法小結,包括基礎執(zhí)行方法、各種執(zhí)行方式的區(qū)別、帶參數(shù)執(zhí)行、調(diào)試模式、環(huán)境變量控制、輸入輸出重定向、后臺執(zhí)行、定時執(zhí)行、條件執(zhí)行、安全執(zhí)行方式以及高級執(zhí)行技巧,感興趣的可以了解一下
1. 基礎執(zhí)行方法
方法1:使用解釋器直接執(zhí)行
方法2:添加執(zhí)行權限后執(zhí)行
# 添加執(zhí)行權限 chmod +x script.sh # 然后直接執(zhí)行 ./script.sh # 或者使用絕對路徑 /home/user/script.sh /path/to/script.sh
方法3:使用source或點命令
# 在當前shell環(huán)境中執(zhí)行 source script.sh # 簡寫形式(功能相同) . script.sh
2. 各種執(zhí)行方式的區(qū)別
子shell執(zhí)行 vs 當前shell執(zhí)行
#!/bin/bash # demo.sh export MY_VAR="子shell變量" echo "MY_VAR: $MY_VAR"
# 測試不同執(zhí)行方式 echo "=== 方法1: bash script.sh ===" bash demo.sh echo "執(zhí)行后MY_VAR: $MY_VAR" # 空值(變量在子shell中) echo "=== 方法2: ./script.sh ===" chmod +x demo.sh ./demo.sh echo "執(zhí)行后MY_VAR: $MY_VAR" # 空值(變量在子shell中) echo "=== 方法3: source script.sh ===" source demo.sh echo "執(zhí)行后MY_VAR: $MY_VAR" # 有值(變量在當前shell)
執(zhí)行方式對比表
| 執(zhí)行方式 | 是否需要執(zhí)行權限 | 是否創(chuàng)建子shell | 變量是否保持 | 退出狀態(tài) |
|---|---|---|---|---|
| bash script.sh | ? 不需要 | ? 是 | ? 不保持 | 腳本最后命令 |
| ./script.sh | ? 需要 | ? 是 | ? 不保持 | 腳本最后命令 |
| source script.sh | ? 不需要 | ? 否 | ? 保持 | 腳本最后命令 |
| . script.sh | ? 不需要 | ? 否 | ? 保持 | 腳本最后命令 |
3. 帶參數(shù)執(zhí)行
傳遞參數(shù)給腳本
#!/bin/bash
# script_with_args.sh
echo "腳本名稱: $0"
echo "參數(shù)個數(shù): $#"
echo "所有參數(shù): $@"
for i in $(seq 1 $#); do
echo "參數(shù) $i: ${!i}"
done
# 執(zhí)行帶參數(shù)的腳本 bash script_with_args.sh arg1 arg2 "arg3 with spaces" ./script_with_args.sh apple banana cherry source script_with_args.sh 參數(shù)1 參數(shù)2
參數(shù)處理示例
#!/bin/bash
# process_args.sh
# 處理選項參數(shù)
while [[ $# -gt 0 ]]; do
case $1 in
-v|--verbose)
VERBOSE=true
shift
;;
-f|--file)
FILE="$2"
shift 2
;;
-h|--help)
echo "用法: $0 [-v] [-f FILE]"
exit 0
;;
*)
echo "未知參數(shù): $1"
exit 1
;;
esac
done
echo "詳細模式: ${VERBOSE:-false}"
echo "文件: ${FILE:-未指定}"
4. 調(diào)試模式執(zhí)行
各種調(diào)試選項
# 顯示執(zhí)行的每一行命令 bash -x script.sh # 顯示變量賦值 bash -v script.sh # 組合調(diào)試 bash -xv script.sh # 檢查語法而不執(zhí)行 bash -n script.sh # 從指定行開始執(zhí)行 bash -x --debugger script.sh
腳本內(nèi)調(diào)試設置
#!/bin/bash
# debug_demo.sh
# 開啟調(diào)試
set -x
echo "這一行會被顯示"
name="Debug Test"
echo "名字: $name"
# 關閉調(diào)試
set +x
echo "這一行不會被顯示"
# 只調(diào)試部分代碼
(
set -x
echo "這部分代碼會調(diào)試"
date
set +x
)
echo "調(diào)試結束"
5. 環(huán)境變量控制執(zhí)行
設置環(huán)境變量
# 臨時設置環(huán)境變量 MY_VAR="value" bash script.sh # 設置多個環(huán)境變量 DEBUG=true LOG_LEVEL=info bash script.sh # 清空環(huán)境變量執(zhí)行 env -i bash script.sh # 空環(huán)境執(zhí)行
修改PATH后執(zhí)行
# 添加自定義路徑到PATH PATH="/my/custom/bin:$PATH" ./script.sh # 使用完整路徑避免PATH依賴 /bin/bash /path/to/script.sh
6. 輸入輸出重定向
重定向標準輸入輸出
# 輸出重定向到文件 bash script.sh > output.txt bash script.sh >> output.txt # 追加模式 # 錯誤輸出重定向 bash script.sh 2> error.log bash script.sh > output.txt 2>&1 # 合并輸出和錯誤 bash script.sh &> all_output.txt # 合并輸出(bash 4.0+) # 輸入重定向 bash script.sh < input.txt echo "input data" | bash script.sh
使用here document
# 直接傳遞輸入數(shù)據(jù) bash script.sh << EOF 第一行輸入 第二行輸入 第三行輸入 EOF # 帶變量替換的here document name="John" age=25 bash script.sh << EOD 姓名: $name 年齡: $age 時間: $(date) EOD
7. 后臺執(zhí)行和作業(yè)控制
后臺執(zhí)行腳本
# 后臺執(zhí)行 bash long_running_script.sh & # 后臺執(zhí)行并忽略掛起信號 nohup bash script.sh & # 后臺執(zhí)行并重定向輸出 nohup bash script.sh > output.log 2>&1 & # 使用screen/tmux保持會話 screen -dm bash script.sh tmux new-session -d bash script.sh
作業(yè)控制
# 啟動后臺作業(yè) bash script.sh & jobs # 查看后臺作業(yè) # 將后臺作業(yè)調(diào)到前臺 fg %1 # 暫停當前作業(yè) Ctrl+Z bg %1 # 在后臺繼續(xù)運行 # 殺死作業(yè) kill %1
8. 定時執(zhí)行和自動化
使用cron定時執(zhí)行
# 編輯crontab crontab -e # 添加定時任務示例 # 每分鐘執(zhí)行 * * * * * /path/to/script.sh # 每天凌晨2點執(zhí)行 0 2 * * * /path/to/script.sh # 每周一上午9點執(zhí)行 0 9 * * 1 /path/to/script.sh # 每月1號執(zhí)行 0 0 1 * * /path/to/script.sh
使用at命令單次執(zhí)行
# 10分鐘后執(zhí)行 echo "/path/to/script.sh" | at now + 10 minutes # 明天上午9點執(zhí)行 at 09:00 tomorrow <<< "/path/to/script.sh" # 查看等待的at任務 atq # 刪除at任務 atrm 任務編號
9. 條件執(zhí)行和管道
條件執(zhí)行
# 只有前一個命令成功才執(zhí)行 bash script1.sh && bash script2.sh # 只有前一個命令失敗才執(zhí)行 bash script1.sh || bash script2.sh # 復雜條件組合 bash script1.sh && echo "成功" || echo "失敗"
管道執(zhí)行
# 腳本輸出作為另一個腳本的輸入 bash generator.sh | bash processor.sh # 多個腳本管道連接 bash script1.sh | bash script2.sh | bash script3.sh # 使用tee同時輸出到屏幕和文件 bash script.sh | tee output.log
10. 安全執(zhí)行方式
安全執(zhí)行最佳實踐
# 使用完整路徑避免PATH劫持 /bin/bash /path/to/script.sh # 使用sudo以特定用戶執(zhí)行 sudo -u username bash script.sh sudo -u www-data bash script.sh # 在受限環(huán)境中執(zhí)行 bash --restricted script.sh # 受限模式 bash --norc script.sh # 不讀取rc文件
權限控制
# 設置適當?shù)奈募嘞? chmod 755 script.sh # 所有者可讀寫執(zhí)行,其他用戶可讀執(zhí)行 chmod 700 script.sh # 只有所有者可讀寫執(zhí)行 # 設置setuid權限(謹慎使用) chmod u+s script.sh # 以文件所有者身份執(zhí)行 # 使用acl進行精細控制 setfacl -m u:username:rx script.sh
11. 高級執(zhí)行技巧
使用exec替換當前進程
#!/bin/bash # exec_demo.sh echo "準備執(zhí)行exec..." exec bash -c 'echo "這是exec執(zhí)行的命令"; sleep 2' echo "這行不會執(zhí)行" # 因為exec替換了當前進程
使用trap處理信號
#!/bin/bash
# trap_demo.sh
cleanup() {
echo "收到信號,正在清理..."
exit 1
}
# 設置信號處理
trap cleanup SIGINT SIGTERM
echo "腳本運行中,按Ctrl+C測試信號處理"
sleep 10
echo "正常結束"
使用coproc協(xié)程
#!/bin/bash
# coproc_demo.sh
# 創(chuàng)建協(xié)程
coproc MY_COPROC {
while read line; do
echo "處理: $line"
done
}
# 向協(xié)程發(fā)送數(shù)據(jù)
echo "數(shù)據(jù)1" >&${MY_COPROC[1]}
echo "數(shù)據(jù)2" >&${MY_COPROC[1]}
# 從協(xié)程讀取數(shù)據(jù)
read -u ${MY_COPROC[0]} result
echo "結果: $result"
12. 實用執(zhí)行腳本示例
批量執(zhí)行腳本
#!/bin/bash
# batch_executor.sh
SCRIPT_DIR="/path/to/scripts"
LOG_DIR="/path/to/logs"
# 確保日志目錄存在
mkdir -p "$LOG_DIR"
# 批量執(zhí)行所有.sh腳本
for script in "$SCRIPT_DIR"/*.sh; do
if [[ -x "$script" ]]; then
script_name=$(basename "$script")
log_file="$LOG_DIR/${script_name}.log"
echo "執(zhí)行: $script_name"
bash "$script" > "$log_file" 2>&1
if [[ $? -eq 0 ]]; then
echo "? $script_name 執(zhí)行成功"
else
echo "? $script_name 執(zhí)行失敗"
fi
fi
done
監(jiān)控腳本執(zhí)行
#!/bin/bash
# script_monitor.sh
SCRIPT="$1"
TIMEOUT=300 # 5分鐘超時
if [[ ! -f "$SCRIPT" ]]; then
echo "錯誤: 腳本不存在: $SCRIPT"
exit 1
fi
# 帶超時執(zhí)行
timeout $TIMEOUT bash "$SCRIPT"
case $? in
0)
echo "腳本執(zhí)行成功"
;;
124)
echo "腳本執(zhí)行超時(超過 ${TIMEOUT}秒)"
;;
*)
echo "腳本執(zhí)行失敗,退出碼: $?"
;;
esac
13. 執(zhí)行方式選擇指南
根據(jù)場景選擇執(zhí)行方式
| 使用場景 | 推薦執(zhí)行方式 | 理由 |
|---|---|---|
| 臨時測試 | bash script.sh | 簡單快捷,無需權限 |
| 生產(chǎn)環(huán)境 | ./script.sh | 正式規(guī)范,權限明確 |
| 配置加載 | source config.sh | 變量在當前shell生效 |
| 調(diào)試排錯 | bash -x script.sh | 顯示執(zhí)行過程 |
| 定時任務 | crontab | 自動化調(diào)度 |
| 后臺服務 | nohup script.sh & | 持久化運行 |
| 管道處理 | `script1.sh | script2.sh` |
| 安全執(zhí)行 | 完整路徑執(zhí)行 | 避免路徑劫持 |
最佳實踐總結
# 1. 生產(chǎn)環(huán)境使用完整路徑 /bin/bash /opt/scripts/myscript.sh # 2. 設置適當?shù)膱?zhí)行權限 chmod 750 /opt/scripts/myscript.sh # 3. 使用日志記錄 /bin/bash /opt/scripts/myscript.sh >> /var/log/myscript.log 2>&1 # 4. 錯誤處理 /bin/bash /opt/scripts/myscript.sh || echo "執(zhí)行失敗" | mail -s "腳本錯誤" admin@company.com # 5. 資源限制 timeout 3600 /bin/bash /opt/scripts/myscript.sh
這個完整的指南涵蓋了Shell腳本執(zhí)行的所有主要方法,從基礎到高級技巧都有詳細說明。根據(jù)具體需求選擇合適的執(zhí)行方式非常重要
到此這篇關于執(zhí)行shell腳本的各種方法小結的文章就介紹到這了,更多相關執(zhí)行shell腳本內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
使用shell腳本每天對MySQL多個數(shù)據(jù)庫自動備份的講解
今天小編就為大家分享一篇關于使用shell腳本每天對MySQL多個數(shù)據(jù)庫自動備份的講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
linux系統(tǒng)下用.sh文件執(zhí)行python命令的方法
這篇文章主要給大家介紹了關于linux系統(tǒng)下用.sh文件執(zhí)行python命令的相關資料,文中通過實例代碼介紹的非常詳細,對大家學習或者使用python具有一定的參考學習價值,需要的朋友可以參考下2022-07-07
Shell腳本實現(xiàn)監(jiān)測文件變化的示例詳解
這篇文章主要和大家分享一個Shell腳本,可以實現(xiàn)監(jiān)測文件變化功能。文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2022-06-06
linux shell之控制臺打印各種顏色字體和背景的實現(xiàn)方法
今天小編就為大家分享一篇關于linux shell之控制臺打印各種顏色字體和背景的實現(xiàn)方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04

