次のように後で呼び出すことができるbashファイルを生成したいと思います。
cat <<-SCRIPT >test-$$
#!/bin/bash
osType=$(grep -Po '^NAME="\K[^"]*' /etc/os-release)
if [ "$osType" = ...]
then
...
fi
exit
SCRIPT
デバッグすると、grepコマンドは常に正しい方法で実行されます。なぜですか?また、awkと同じエラーを試してみました。
しかし、私がそうするなら
cat <<-SCRIPT >test-$$
#!/bin/bash
rpm -q somepackage > test-$$
rm test-$$-lock
exit
SCRIPT
rpmコマンドが正しい方法で実行されるのを見ることができませんか? test-$$とtest-$$-lockも同じ$$を持っていますか?
ベストアンサー1
here-docのようなものは<<-SCRIPT
拡張が内部で処理されるため、二重引用符で囲まれた文字列のように動作します。これを防ぐために、区切り文字を引用してください。
$ cat <<EOF
1+1 = $((1+1))
EOF
1+1 = 2
そして
$ cat <<'EOF'
1+1 = $((1+1))
EOF
1+1 = $((1+1))
だからここにあります:
cat <<-SCRIPT >test-$$
...
osType=$(grep -Po '^NAME="\K[^"]*' /etc/os-release)
コマンドはgrep
コマンド置換にあり、SCRIPT
引用符なしで処理されるため、ここでドキュメントを使用すると実行されます。
一方、ここでは:
cat <<-SCRIPT >test-$$
#!/bin/bash
rpm -q somepackage > test-$$
rm test-$$-lock
exit
SCRIPT
コマンド置換がないため、コマンドは実行されません。このrpm -q somepackage
セクションはテキストだけです。ただし、引用符のない区切り文字を使用すると、$$
ここのドキュメントの内部は出力ファイル名で使用されているのと同じ値にすぐに拡張されます。つまり、現在のシェルのPIDが1234の場合、このコマンドはインクルードラインをcat
生成します。test-1234
rpm -q somepackage > test-1234
引用符で囲まれた区切り文字を使用すると、そのまま残り、$$
結果はインクルードと呼ばれtest-1234
ますrpm -q somepackage > test-$$
。test-1234
今スクリプトで実行すると$$
拡張されますそれシェルのPIDが使用されます。ファイルの作成に使用された値と異なる場合があります。
それにもかかわらず、$$
同じrpm .. > test-$$
値rm test-$$-lock
に拡張されます。