Gitコミットコメントから入力を受け取り、それ自体を更新するbashスクリプトを確認してください。単純化する:
script
:
#!/bin/bash
comment=''
printf '%s\n' "$comment"
upgrade_script() {
# Download latest:
curl -o updated_script https://path/to/file
# Get comment:
new_comment="$(curl https://path/to/comment)"
# Update comment='' with new_comment:
sed -i "3,0 s/comment=''/comment='$new_comment'/" updated_script
}
問題は、コメントに中断sed
またはmangles
クン文字が含まれているかどうかです。たとえば、
# that's all she wrote! => comment='that's all she wrote!
# use /need/ over /want/ => s/comment=''/'use /need/ over /want'/'
もちろん、悪意のある意図がある可能性もありますが、次のような予期しないこともあるかもしれません。
# Remove tmp files by: ' rm -r *;' => comment='Remove tmp files by: ' rm -r *;''
これで問題を解決するのに十分ですか?
コマンドの前に以下を追加しますsed -i
。
new_comment=$(
sed \
-e "s/'/'\"'\"'/g" \
-e 's/[&\\/]/\\&/g; s/$/\\/; $s/\\$//'<<< "$new_comment"
)
のためbash
:
'
使用。 。 。交換'"'"'
。
のためsed
:
- エスケープ文字
&
、\
および/
行終端。
それとも、どのような失敗が起こるのでしょうか?
理想的には、これは何もしませんが、知りたいのですが。
注:
別のソリューション、ファイルとして保存、exit
スクリプトにを追加し、その後にテキストを追加してから、などsed
を使用して印刷することもできます。しかし、それは私の問題ではありません。
#!/bin/bash
code
code
code
# When in need of the comment:
sed -n '/^exit # EOF Script$/$ {/start_xyz/,/end_xyz/ ...}'
# or what ever. Could even record offset and byte-length safely
code
code
exit # EOF Script
start_xyz
Blah blah blah
blaah
end_xyz
これを念頭に置いて、次のように推測します。
comment=<<<'SOF'
...
SOF
SOF
早期終了を防ぐには、どちらかを交換するだけです。私の質問はまだ消毒する以上。ありがとうございます。
答え1
以下を組み合わせる必要があるようです。
だから:
#! /bin/bash -
comment=''
printf '%s\n' "$comment"
upgrade_script() {
local - new_comment quoted_for_sh quoted_for_sed_and_sh
set -o pipefail
# Get comment:
new_comment="$(curl https://path/to/comment)" || return
quoted_for_sh=\'${new_comment//\'/\'\\\'\'}\'
quoted_for_sed_and_sh=$(
printf '%s\n' "$quoted_for_sh" |
LC_ALL=C sed 's:[\\/&]:\\&:g;$!s/$/\\/'
) || return
curl https://path/to/file |
# Update comment='' with new_comment:
LC_ALL=C sed "3s/comment=''/comment=$quoted_for_sed/" > updated_script
}
zsh + perlはbash + sedよりも良い選択ですが:
#! /bin/zsh -
comment=''
print -r -- $comment
upgrade_script() {
set -o localoptions -o pipefail
local new_comment quoted_for_sh
# Get comment:
new_comment=$(curl https://path/to/comment) || return
quoted_for_sh=${(qq)new_comment}
curl https://path/to/file |
# Update comment='' with new_comment:
perl -pse "s/comment=\K''/$repl/ if $. == 3
' -- -repl=$quoted_for_sh > updated_script
}
NUL文字を含めることができることに注意してくださいcomment
。これはzshとその組み込み機能には適していますが、外部コマンドに引数として渡すことはできません。 NULをbash
削除します$(...)
。
これらのリスクを排除するには、curl
出力をパイプしてNULを手動で削除するtr -d '\0'
か、
new_comment=${new_comment//$'\0'}
またはそのような役割がある場合は終了します。
[[ $new_comment = *$'\0'* ]] && die 'Something dodgy going on'