readvar.shというスクリプトがあります。
#! /bin/bash
a="$1"
echo "$a"
パラメータを取得したいです。文字通りユーザーが入力すると、
たとえば、ユーザーが次を実行する場合:./readvar.sh \\
\\
パラメータの周囲に引用符なしで出力する必要があります。
それは可能ですか?
ベストアンサー1
一般的に言えば、これはできません。
runの場合、./readvar.sh \\
コマンドが書かれたシェルはコマンドラインを解析し、スペースを単語区切り文字として認識し、バックスラッシュを次の文字(別のバックスラッシュ)を引用することを認識します。その後、./readvar.sh
2つの単語で終わり、\
プログラムを起動して./readvar.sh
その2つの単語をプロセスを開始するパラメータのリストに入れます。 (コマンド名はargv[0]
Cプログラムに出てくるパラメータ#0です。)
./readvar.sh '\'
ユーザーがPerlプログラムなどを使用してスクリプトを入力または起動すると、同様のbs='\'; ./readvar "$var"
結果が得られます。system("./readvar.sh", "\\");
スクリプトには通常、何が起こっているのかを知る方法はありません。
あなたができることは、シェル入力に適した形式ですべての引数を印刷することです。たとえば、Bashでは次のように使用します。
if [ "$#" -ne 0 ]; then
printf "%q " "$@"
fi
echo
出力はBashで動作しますが、$'\n'
改行などの形式で引用符を使用するため、標準シェルでは機能しない可能性があります。また、スクリプトを\\
使用または起動するたびに出力されます。\\
'\'
"\\"
Bashでもこれを乱用する可能性がありますextdebug
。これは、実行中のコマンドのコンテキストに、BashのDEBUGトラップに表示されるコマンドラインを配置します。
export CMDLINE
trap 'CMDLINE=$BASH_COMMAND; true' DEBUG
shopt -s extdebug
ただし、そこにあるコマンドラインは拡張されていないため、実行すると代わりに拡張値がenv abc=$var |grep CMD
表示されます。env abc=$var
もちろん、追加の手順を実行する Bash シェルでコマンドが実行されない場合は機能しません。プロセスツリーの親にこれらのシェルがある場合は、前のCMDLINE
コマンドを実行するコマンドとして設定できます。
今、これらのトリッキーな回避策が存在しますが、スクリプトユーザーがスクリプトが最終的に実行する必要があるタスクを達成するために他の方法を使用する方が良いと驚くべきことではないかもしれません。