シェルスクリプトで、呼び出されたすべてのシェルコマンドをエコーして変数名を展開する方法を教えてください。
たとえば、次の行があるとします。
ls $DIRNAME
スクリプトでコマンドを実行して次のように表示します。
ls /full/path/to/some/dir
目的は、呼び出されたすべてのシェルコマンドとその引数のログを保存することです。そのようなログを生成するためのおそらくよりよい方法はありますか?
set -x
またはset -o xtrace
は、変数を展開して行の前に小さな+記号を表示します。
set -v
またはset -o verbose
は、印刷前に変数を展開しません。
上記の設定を無効にするには、set +x
とset +v
を使用します。
スクリプトの最初の行に、スクリプトの後半で#!/bin/sh -x
(または-v
)と同じ効果を持たせるためにset -x
(または-v
)を配置できます。
上記は/bin/sh
でも動作します。
set
の属性 および debugging のbash-hackersのwikiを参照してください。
$ 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
関数を使ってエコーしてからコマンドを実行します
#!/bin/bash
#function to display commands
exe() { echo "\$ $@" ; "$@" ; }
exe echo hello world
どの出力
$ echo hello world
hello world
編集する
もっと複雑なコマンドパイプなどにはevalを使うことができます。
#!/bin/bash
#function to display commands
exe() { echo "\$ ${@/eval/}" ; "$@" ; }
exe eval "echo 'Hello World' | cut -d ' ' -f1"
どの出力
$ echo 'Hello World' | cut -d ' ' -f1
Hello
shuckcの選択行のエコーに対する回答にはいくつかの欠点があります。次のset +x
コマンドもエコーされることになり、$?
で終了コードを上書きするため終了コードをテストすることができなくなります。 set +x
。
別のオプションは、サブシェルでコマンドを実行することです:
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
ただし、これにより、コマンドの新しいサブシェルを作成するオーバーヘッドが発生します。
別のオプションは、コマンドラインではなく、スクリプトの先頭に "-x"を付けることです。
$ cat ./server
#!/bin/bash -x
ssh user@server
$ ./server
+ ssh user@server
user@server's password: ^C
$
(選択した回答にコメントするには担当者が不十分です。)
_ tldp _ による 初心者向けBashガイド:第2章スクリプトの作成とデバッグ
2.3.1。スクリプト全体のデバッグ
$ bash -x script1.sh
...
SourceForge で入手可能なBash用の本格的なデバッガーがあります。これらのデバッグ機能は、3.x以降の最新バージョンのBashで使用できます。
2.3.2。スクリプトの一部のデバッグ
set -x # activate debugging from here w set +x # stop debugging from here
...
表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
コマンドラインでbashスクリプトの名前の前に「bash -x」と入力します。たとえば、foo.shを実行するには、次のように入力します。
bash -x foo.sh
デバッグモードでは、-xオプションを使用してbashスクリプトをexecuteできます。
これはすべてのコマンドをエコーします。
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
上記の誰かが投稿しました:
#!/bin/bash
#function to display commands
exe() { echo "\$ $@" ; "$@" ; }
そして、これは有望に見えます、しかし、私は私の人生のためにそれが何をするかについて理解することができません。私はグーグルでman bashページで "\ $"と "$ @"を検索しましたが、絶対に nothing を見つけました。
"exec()"という名前の関数が作成されているのがわかります。中括弧は関数の始まりと終わりを表します。セミコロンは複数行のコマンドの間の「ハードリターン」を示していると私は理解していると思います。その結果、 '{echo "\ $ $ @"; "$ @";本質的には、
{
echo "\$ $@"
"$@"
}
誰かが私に簡単な説明を、またはどこでこの情報を見つけるために与えることができます、明らかに私のgoogle-fuは私に失敗しているので?
(古いスレッドで新しい質問を始めることを意味するものではなく、私の目的は出力をファイルに転送することです。 "set -x; [commands]; set + x"メソッドは私には十分うまくいくでしょうが。画面ではなくファイルに結果を表示する方法を理解するために、リダイレクト/パイプ/ティーなどの理解が非常に乏しいことを期待して、この他の方法を理解しようとしていました。)
ありがとうございます。
後編集:
少し手を加えて、私はそれを考え出したと思います。これが、私が必要としているものと同等のコードです。
SCRIPT_LOG="\home\buddy\logfile.txt"
exe () {
params="$@" # 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
必要なものだけ。ありがとうございます。
Zshエコー用
setopt VERBOSE
そしてデバッグ用
setopt XTRACE
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
関数を使用してからコマンドを実行します。これは、他の方法ではパイプコマンドの何も表示されない、または最初の部分だけが表示されるようなパイプコマンドに役立ちます。
評価なし
exe() { echo "\$ $@" ; "$@" ; }
exe ls -F | grep *.txt
出力:
$
file.txt
評価付き:
exe() { echo "\$ $@" ; "$@" ; }
exe eval 'ls -F | grep *.txt'
どの出力
$ exe eval 'ls -F | grep *.txt'
file.txt