10

簡単なスクリプトを出力して出力をファイルにリダイレクトする必要がありますが、これを行うと:

printf "#!/bin/bash\ntouch /tmp/1234567890_$RUN" > /tmp/password-change-script_$RUN.sh

次のエラーが表示されます。

bash: !/bin/bash\ntouch: イベントが見つかりません

感嘆符をエスケープした場合:

printf "#\!/bin/bash\ntouch /tmp/1234567890_$RUN" > /tmp/password-change-script_$RUN.sh

その後、エスケープ文字がまだファイルに存在します。

cat /tmp/password-change-script_$RUN.sh
#\!/bin/bash
touch /tmp/1234567890_111

ちなみに、この特定のケースでは、 #!/bin/bash がファイルに含まれている必要があります。何らかの理由で、スクリプトを実行するバイナリ ファイルは、それ以外の場合はファイルを読み取れません。

4

2 に答える 2

16

文字は二重引用符で囲まれた!文字列では展開されますが、単一引用符で囲まれた文字列では展開されません。

printf '#!/bin/bash\ntouch /tmp/1234567890_'"$RUN"

また、単独で表示される場合や単語の末尾に表示される場合も展開されません。これはきれいではありませんが:

printf "#%c/bin/bash\ntouch /tmp/1234567890_$RUN" !

$histchars空の文字列を(一時的に) 設定することで、履歴置換を一時的にオフにすることもできます。これは の特別な扱いをオフにします!:

histchars=
printf "#!/bin/bash\ntouch /tmp/1234567890_$RUN"
unset histchars

printfまたは、対話的にではなく、スクリプトでコマンドを実行することもできます(履歴置換は、対話型シェルに対してのみデフォルトでオンになっています)。

于 2013-02-21T20:48:18.440 に答える
12

これをやってみてください:

printf "\041"

!これは、文字の 8 進 ASCII 表現です。

見る

man ascii

別の解決策:

(
    set +o histexpand 
    printf "!"
)

(括弧はサブシェルの端末設定を変更するために使用されるため、変更は一時的なものです)

見る

help set
set -o
于 2013-02-21T20:44:34.697 に答える