在shell腳本中,我如何回顯所有調用的shell命令並展開所有變量名稱? 例如,給出以下行:在shell腳本中:執行echo shell命令
ls $DIRNAME
我想腳本來運行該命令,並顯示以下
ls /full/path/to/some/dir
目的是保存日誌的所有shell命令的調用,其參數。也許有更好的方法來生成這樣一個日誌?
在shell腳本中,我如何回顯所有調用的shell命令並展開所有變量名稱? 例如,給出以下行:在shell腳本中:執行echo shell命令
ls $DIRNAME
我想腳本來運行該命令,並顯示以下
ls /full/path/to/some/dir
目的是保存日誌的所有shell命令的調用,其參數。也許有更好的方法來生成這樣一個日誌?
set -x
或set -o xtrace
展開變量並在行之前打印一個+號。
set -v
或set -o verbose
在打印前不擴展變量。使用set +x
和set +v
來關閉上述設置。
在腳本的第一行中,一個可以把#!/bin/sh -x
(或-v
)具有相同的效果set -x
(或-v
)後面的腳本。
以上也適用於/bin/sh
。
http://www.faqs.org/docs/abs/HTML/options.html
$ cat shl
#!/bin/bash
DIR=/tmp/so
ls $DIR
$ bash -x shl
+ DIR=/tmp/so
+ ls /tmp/so
$
set -x
會給你想要的東西。
下面是一個例子外殼腳本來證明:
#!/bin/bash
set -x #echo on
ls $PWD
這擴大所有變量和指令的輸出之前打印的全部命令。
輸出:
+ ls /home/user/
file1.txt file2.txt
您還可以通過在set -x
和set +x
例如包裹他們切換此爲選擇行腳本
#!/bin/bash
...
if [[ ! -e $OUT_FILE ]];
then
echo "grabbing $URL"
set -x
curl --fail --noproxy $SERV -s -S $URL -o $OUT_FILE
set +x
fi
另一種選擇是把「-X」在你的腳本的頂部,而不是在命令行中:(代表不足,無法發表評論,選擇的答案)
$ cat ./server
#!/bin/bash -x
ssh [email protected]
$ ./server
+ ssh [email protected]
[email protected]'s password: ^C
$
請注意,這似乎並沒有在'./myScript'和'bash myScript'之間完全相同。還有一件好事要指出,謝謝。 – altendky 2015-04-16 14:08:39
對於zsh的呼應
setopt VERBOSE
和調試
setopt XTRACE
shuckc的回送選擇線路的答案有幾個缺點:你最終有以下set +x
命令被回送爲好,你失去與$?
測試退出代碼,因爲它得到由set +x
覆蓋的能力。
另一種選擇是在子shell中運行以下命令:
echo "getting URL..."
(set -x ; curl -s --fail $URL -o $OUTFILE)
if [ $? -eq 0 ] ; then
echo "curl failed"
exit 1
fi
,這將給你的輸出,如:
getting URL...
+ curl -s --fail http://example.com/missing -o /tmp/example
curl failed
這確實招致了命令創建一個新的子shell的開銷,雖然。
避免++集+ x輸出的好方法。 – 2015-01-09 15:23:35
甚至更好:替換'if [$? -eq 0]'帶'if(set -x; COMMAND)'。 – 2017-01-02 10:35:57
在bash腳本的名稱之前的命令行中鍵入「bash -x」。例如,爲了執行foo.sh,類型:
bash -x foo.sh
使用函數來呼應然後運行命令
#!/bin/bash
#function to display commands
exe() { echo "\$ [email protected]" ; "[email protected]" ; }
exe echo hello world
其輸出
$ echo hello world
hello world
編輯:
對於更復雜的命令管道等,你可以使用eval:
#!/bin/bash
#function to display commands
exe() { echo "\$ ${@/eval/}" ; "[email protected]" ; }
exe eval "echo 'Hello World' | cut -d ' ' -f1"
,輸出
$ echo 'Hello World' | cut -d ' ' -f1
Hello
對於csh
和tcsh
,你可以set verbose
或set echo
(或者你甚至可以同時設置,但它可能會導致一些重複的大部分時間)。
verbose
選項幾乎打印出您輸入的確切shell表達式。
echo
選項更多地指示將通過產卵執行什麼。
http://www.tcsh.org/tcsh.html/Special_shell_variables.html#verbose
http://www.tcsh.org/tcsh.html/Special_shell_variables.html#echo
Special shell variables
verbose If set, causes the words of each command to be printed, after history substitution (if any). Set by the -v command line option.
echo If set, each command with its arguments is echoed just before it is executed. For non-builtin commands all expansions occur before echoing. Builtin commands are echoed before command and filename substitution, because these substitutions are then done selectively. Set by the -x command line option.
要允許複合命令被回顯,我使用eval
加上Soth的exe
函數來回顯然後運行該命令。這對管道命令非常有用,否則這些命令只會顯示任何內容或僅顯示管道命令的初始部分。
沒有EVAL:
exe() { echo "\$ [email protected]" ; "[email protected]" ; }
exe ls -F | grep *.txt
輸出:
$
file.txt
隨着EVAL:
exe() { echo "\$ [email protected]" ; "[email protected]" ; }
exe eval 'ls -F | grep *.txt'
,輸出
$ exe eval 'ls -F | grep *.txt'
file.txt
據TLDP的Bash Guide for Beginners: Chapter 2. Writing and debugging scripts
2.3.1。在調試整個腳本
$ bash -x script1.sh
...
現在有猛砸一個全面的調試器,可在SourceForge。這些調試功能在大多數現代版本的Bash中都可用,從3.x開始。
2.3.2。在調試腳本
set -x # activate debugging from here w set +x # stop debugging from here
的一部分(S)...
表2-1。的集合調試選項
Short | Long notation | Result
-------+---------------+--------------------------------------------------------------
set -f | set -o noglob | Disable file name generation using metacharacters (globbing).
set -v | set -o verbose| Prints shell input lines as they are read.
set -x | set -o xtrace | Print command traces before executing command.
概述...
可替代地,這些模式可以在腳本本身指定的,通過添加 到第一線殼聲明所需的選項。 的選項可以進行組合,如通常在UNIX的情況下命令:
#!/bin/bash -xv
有人張貼以上:
#!/bin/bash
#function to display commands
exe() { echo "\$ [email protected]" ; "[email protected]" ; }
和這個l ooks很有希望,但我不能爲了我的生活找出它的作用。我已經搜索了「\ $」和「$ @」的man bash頁面,並且絕對找不到。
我明白正在創建一個名爲「exec()」的函數。我明白花括號標記了函數的開始和結束。我認爲我明白分號標誌着多行命令之間的「硬迴歸」,因此'{echo'\ $ $ @「; 「$ @」; }」成爲在本質:
{
echo "\$ [email protected]"
"[email protected]"
}
任何一個可以給我一個簡要的解釋,或在哪裏可以找到這些信息,因爲很明顯我的谷歌福失敗了我? (set -x; [commands]; set + x「)方法對我來說是非常有效的,因爲這個方法對我來說非常適合,但我無法弄清楚如何將結果回顯到文件而不是屏幕,所以我試圖理解這種其他方法,希望我可以使用我對重定向/管道/ tee /等的相當差的理解來做同樣的事情東西)。
謝謝!
以後編輯:
與一些修修補補,我相信我想通了。這裏是我的等同的代碼,就是我需要:
SCRIPT_LOG="\home\buddy\logfile.txt"
exe() {
params="[email protected]" # Put all of the command-line into "params"
printf "%s\t$params" "$(date)" >> "$SCRIPT_LOG" # Print the command to the log file
$params # Execute the command
}
exe rm -rf /Library/LaunchAgents/offendingfile
exe rm -rf /Library/LaunchAgents/secondoffendingfile
在LOGFILE.TXT看起來類似的結果:
Tue Jun 7 16:59:57 CDT 2016 rm -rf /Library/LaunchAgents/offendingfile
Tue Jun 7 16:59:57 CDT 2016 rm -rf /Library/LaunchAgents/secondoffendingfile
正是我需要的。謝謝!
我相信我明白了。這裏是我的等同的代碼,就是我需要: EXE(){ PARAMS = 「$ @」 \t \t \t \t \t \t#把所有的命令行中的 「PARAMS」 的printf「%S \ T $ PARAMS 「 」$(日期)「 >> 」$ SCRIPT_LOG「 \t#打印命令將日誌文件 $ PARAMS \t \t \t \t \t \t \t#執行命令} \t EXE室射頻/庫/ LaunchAgents/COM .carbonite.launchd.carbonitealerts.plist \t exe rm -rf /Library/LaunchAgents/com.carbonite.launchd.carbonitestatus.plist – DebianFanatic 2016-06-07 21:53:07
需要\ n在'printf'%s \ t $ params「」$(date)「中打破行」$ SCRIPT_LOG「' – user3762200 2017-08-16 15:22:07
您可以執行在調試模式下的bash腳本與-x選項。
這將回顯所有的命令。
bash -x example_script.sh
# Console output
+ cd /home/user
+ mv text.txt mytext.txt
您也可以保存-x選項在腳本。只需在shebang中指定-x選項即可。
######## example_script.sh ###################
#!/bin/bash -x
cd /home/user
mv text.txt mytext.txt
##############################################
./example_script.sh
# Console output
+ cd /home/user
+ mv text.txt mytext.txt
使用單詞 「詳細」 這樣不會完成任何事情。你可以執行'set -o verbose'或'set -v'(只有「verbose」)或'set -o xtrace'或'set -x'(只有「xtrace」)或'set -xv'(兩者)或'set -o xtrace -o verbose'(兩者)。 – 2010-05-18 01:03:05
這很好,但請注意,「詳細」會覆蓋$ 1 – JasonS 2013-06-13 02:04:48
@jasonS *。但是,我沒有想到,好, – Wyatt8740 2016-07-12 18:03:39