web-dev-qa-db-ja.com

シェル拡張を印刷することは可能ですか?

ユーザーが入力したコマンドをシェルが展開する特定のルールセットがあることを知っています。 (bashシェルについて話しましょう。)

シェル展開後のフォームにコマンドを出力することはできますか? Shellが特殊文字をどのように拡張するかを学び、確認することは良いユーティリティのようです。

例えば.

$ echo *

{all the filenames in current dir}

次の行である展開されたコマンドを出力したいと思います。

echo {all the filenames in .}
18
Weishi Zeng

echo...を使用して、展開するコマンドの前に配置します。私はこれをかなり頻繁に使用します。

$ ls
one.txt
two.txt
three.dat
$ echo rm *.txt
rm one.txt two.txt
$ rm *.txt

使用できます Home そして Del 前のechoをすばやく追加/削除します。

[〜#〜]編集[〜#〜]
コメントで 指摘されているように 、コマンドが単なるコマンドではない場合(forループの場合のように、パイプ|を使用する場合など)、これは機能しません。 、または&&またはそのような何か)。

13
BenjiWiebe

set -xを使用できます。

たとえば、次のスクリプトを考えてみます。

$ cat script.sh
set -x
echo *

実行すると、実際に実行する前に展開されたechoステートメントが表示されます。

$ bash script.sh
+ echo file1 file2 file3 script.sh
file1 file2 file3 script.sh

そして、Kundorが指摘しているように、これはinteractivelyでも機能します:

$ set -x
+ set -x
$ echo *
+ echo file1 file2 file3 script.sh
file1 file2 file3 script.sh

ドキュメンテーション

man bashは、set -xの機能を次のように説明しています。

各単純コマンドを展開した後、コマンド、ケースコマンド、選択コマンド、またはコマンドの算術演算の場合、PS4の展開値を表示し、続いてコマンドとその展開引数または関連するワードリストを表示します。

PS4のデフォルト値は、上記のように、プラス記号とそれに続くスペースです。

14
John1024

インタラクティブシェルの場合、globパターンを入力した後にCtrl+xを押してから*を押すと、そのglobパターンが展開された状態でコマンドラインが編集されます。 bashのmanページから:

glob-expand-Word(C-x *

Word before pointはパス名拡張のパターンとして扱われ、一致するファイル名のリストが挿入され、Wordが置き換えられます。数値引数が指定されている場合、パス名展開の前にアスタリスクが追加されます。

Glob-list-expansions(Ctrl+xg)にも興味があるかもしれません。

7
jamesdlin

引数がどのように展開またはトークン化されるかを確認したい場合は、その引数を出力するプログラムまたはスクリプトを使用できます。 bashの実装の1つは次のとおりです。

#!/bin/bash

for (( i = 0; i <= $#; ++i )); do
    printf 'argv[%d] = %s\n' $i "${!i}"
done

それをprintargs.shというファイルに入れて(そして実行可能にした)とすると、次のような出力が得られます。

$ ./printargs.sh a{1..3}b
argv[0] = ./printargs.sh
argv[1] = a1b
argv[2] = a2b
argv[3] = a3b
1
jjlin