1120

シェルスクリプトで、呼び出されたすべてのシェルコマンドをエコーし​​、変数名を展開するにはどうすればよいですか?

たとえば、次の行があるとします。

ls $DIRNAME

スクリプトでコマンドを実行し、次のように表示したいのですが

ls /full/path/to/some/dir

目的は、呼び出されたすべてのシェルコマンドとその引数のログを保存することです。そのようなログを生成するためのより良い方法はおそらくありますか?

4

14 に答える 14

1284

set -xまたはset -o xtrace変数を展開し、行の前に小さな+記号を出力します。

set -vまたはset -o verbose、印刷前に変数を展開しません。

set +xおよびを使用set +vして、上記の設定をオフにします。

スクリプトの最初の行に、スクリプトの後半(または)と同じ効果を持つように#!/bin/sh -x(または)を置くことができます。-vset -x-v

上記は。でも機能し/bin/shます。

set属性デバッグについては、bash-hackersのwikiを参照してください。

$ cat shl
#!/bin/bash                                                                     

DIR=/tmp/so
ls $DIR

$ bash -x shl 
+ DIR=/tmp/so
+ ls /tmp/so
$
于 2010-05-18T00:06:07.993 に答える
382

set -xあなたが望むものをあなたに与えるでしょう。

以下に、デモンストレーション用のシェルスクリプトの例を示します。

#!/bin/bash
set -x #echo on

ls $PWD

これにより、すべての変数が展開され、コマンドの出力前に完全なコマンドが出力されます。

出力:

+ ls /home/user/
file1.txt file2.txt
于 2010-05-18T00:12:12.673 に答える
114

関数を使用して、コマンドをエコーし​​て実行します。

#!/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
于 2014-04-28T13:21:12.643 に答える
97

スクリプト内の選択した行をラップして、たとえば、これを切り替えることもでき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
于 2012-12-05T08:09:00.233 に答える
74

選択行をエコーするための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

ただし、これには、コマンドの新しいサブシェルを作成するオーバーヘッドが発生します。

于 2013-10-15T22:34:03.807 に答える
40

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
于 2015-12-01T11:05:54.923 に答える
38

もう1つのオプションは、コマンドラインではなくスクリプトの先頭に「-x」を配置することです。

$ cat ./server
#!/bin/bash -x
ssh user@server

$ ./server
+ ssh user@server
user@server's password: ^C
$
于 2013-05-12T20:24:35.730 に答える
29

オプションを使用して、デバッグモードでBashスクリプトを実行できます。-x

これにより、すべてのコマンドがエコーされます。

bash -x example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt

スクリプトに-xオプションを保存することもできます。-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
于 2017-09-05T14:50:54.953 に答える
22

コマンドラインでBashスクリプトの名前の前に「bash-x」と入力します。たとえば、foo.shを実行するには、次のように入力します。

bash -x foo.sh
于 2014-03-15T17:40:39.733 に答える
11

すべての答えを組み合わせると、これが最良で最も単純であることがわかりました

# https://stackoverflow.com/a/64644990/8608146
exe(){
    set -x
    "$@"
    { set +x; } 2>/dev/null
}
# example
exe go generate ./...

{ set +x; } 2>/dev/nullhttps://stackoverflow.com/a/19226038/8608146から

ここで説明するように、コマンドの終了ステータスが必要な場合

使用する

{ STATUS=$?; set +x; } 2>/dev/null

そして最後の$STATUSように後者を使用してくださいexit $STATUS

もう少し便利なもの

# https://stackoverflow.com/a/64644990/8608146
_exe(){
    [ $1 == on  ] && { set -x; return; } 2>/dev/null
    [ $1 == off ] && { set +x; return; } 2>/dev/null
    echo + "$@"
    "$@"
}
exe(){
    { _exe "$@"; } 2>/dev/null
}

# examples
exe on # turn on same as set -x
echo This command prints with +
echo This too prints with +
exe off # same as set +x
echo This does not

# can also be used for individual commands
exe echo what up!
于 2020-11-02T11:46:27.950 に答える
4

zshの場合、echo

setopt VERBOSE

そしてデバッグのために、

setopt XTRACE
于 2013-08-20T13:47:31.870 に答える
2

複合コマンドをエコーできるようにするために、evalplusSothの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
于 2015-01-27T17:49:27.643 に答える
1

cshおよびの場合、またはを使用tcshできます(または、両方を設定することもできますが、ほとんどの場合、重複が発生する可能性があります)。set verboseset echo

このverboseオプションは、入力したシェル式とほぼ同じものを出力します。

この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.

于 2014-06-29T22:27:22.417 に答える
0
$ cat exampleScript.sh
#!/bin/bash
name="karthik";
echo $name;

bash -x exampleScript.sh

出力は次のとおりです。

ここに画像の説明を入力してください

于 2016-02-10T17:04:05.287 に答える