OPTERR
私は動作に影響を与えるシェル変数を持つgetoptsを使用しています。OPTERR
getoptsの動作に影響を与えるために、getoptsの値を変更して同じ行からgetoptsを呼び出したいのですが、デフォルト値にOPTERR
戻したいと思います。したがって、変数変更コマンドの呼び出しを混在させるプロセスについて少し曖昧であることを考慮して、簡単なことを試してみましょうecho
。これは一連のシェルコマンドとその出力で、そのうちのいくつかは私には理解されていません。
$ echo OPTERR
1
$ OPTERR=0 echo $OPTERR
1
今はここで止まります。 2番目のコマンドの出力は「0」でなければなりませんか?それで、この質問をする前に、私は頭をつかみ、次のコマンドがサブシェルにある必要があるので、それがあると思いました。だから試してみました...
$ OPTERR=0 (echo $OPTERR)
-bash: syntax error near unexpected token `('
これはもっと驚くべきことです。上記の構成に構文エラーがある場合は、サブシェルを実行するためにシェル変数の値をどのように変更できますか? (また、echoコマンドの後に端末「;」を入れようとしましたが、同じ結果が得られました。)私も試してみました...
$OPTERR=0 bash -c 'echo $OPTERR'
1
したがって、そこにも喜びはありません。別の方法を選んだが..
$function sf() { echo $OPTERR }
$sf
1
$OPTERR=0 sf
0
$sf
1
成功! !しかし、なぜ?この機能は特にサブシェルではなく(そうではありません)、これは実際に私が望むものではありません(私のアプリケーションで動作するようにすることはできますが)。動作する別の式は次のとおりです。
$function sf() { (OPTERR=0; echo $OPTERR;) }
$sf
0
$echo $OPTERR
1
これは私が望むものと非常に似ていますが、もちろん実際のスクリプト(私は些細なことではありません)はこれをecho
行うことを意図しており、スクリプトの残りの部分で見ることができる変数を変更する必要があります。そのため、単純なスクリプトを次の単純な変数セットに変更しました。getopts
getopts
echo
$function sf() { foo='bar'; (foo='check'; echo $foo;); echo $foo; }
$sf
check
bar
ああ! !だからgetopts
私が望む環境に呼び出すことはできますが、サブシェルでは何の値も取得できません。私はここにリストするにはあまりにも恥ずかしいfooとすべての種類のアイテムをエクスポートしようとしましたが、ここに私の問題があります。私のすべての実験をまとめると、これらすべてがどのように機能するのかという根本的に間違ったモデルが明らかになります。私の理解には何がありましたか?正しいアプローチは何ですか?
もう一度申し上げますが、私がしたいのは、withを使用してゼロに設定される関数を作成することですgetopts
。OPTERR
理想的には、関数を呼び出される行に設定せずに、OPTERR
関数の外部から復元するように設定することです。ほとんどのOPTERR
重要なことは、実際に処理できる方法でgetopts
問題が多いように聞こえますが、かなり合理的であり、OPTERR
この変数の存在はそれが可能でなければならないことを示唆しています。
ベストアンサー1
$ echo $VAR
$VAR
これは、シェルがコマンドラインから展開した後にのみ変数割り当てを適用するため、以前の値を提供します。
IFS= read -r foo
ただし、Webサイトでよく見られる構成は、コマンドラインからインポートするのでread
はなく内部で使用するために機能します。IFS
同様にOPTERR=0 getopts ...
動作する必要があります。
$ cat arg.sh
#!/bin/bash
OPTERR=0 getopts a:b var
echo "var: $var OPTERR: $OPTERR"
$ bash arg.sh -z
var: ? OPTERR: 1
オプションが無効な場合でも、-z
エラーメッセージは表示されません。
$ OPTERR=0 bash -c 'echo $OPTERR'
特別なのでちょっと特別ですOPTERR
。 Bashのマニュアルページは次のように述べています。
OPTERR
値に設定すると、1
Bashは組み込みコマンドによって生成されたエラーメッセージを表示しますgetopts
。OPTERR
シェルが呼び出されるか、シェルスクリプトが実行されるたびに 1 に初期化されます。
しかし、アイデアは正確であり、通常の変数で動作します。
$ FOO=123 bash -c 'echo $FOO'
123
私がしたいのは、次のような関数を作成することです。
getopts
関数の引数を解析し、それをネイティブプログラム(たとえばdothis -a; dothis -b -c
)から数回呼び出し、その関数を使用してシェルの引数()を解析しない場合は、変数も変更する必要があることにparse_args "$@"
注意してください。また、その機能に合わせてローカライズする必要があります。getopts
OPTIND
たとえば、ここでは、2番目の関数呼び出しにオプションは表示されません。
foo() { while getopts "abcd" opt; do echo "$opt"; done; };
foo -a -a
foo -b -b
以前の機能と組み合わせると、この機能は自動的に機能します。
foo() {
local OPTIND=1
while OPTERR=0 getopts "abcd" opt; do
echo "$opt"
done
}