私はBash 5.1.8を使用しています。実行すると、man
マニュアルページが表示されますが、次のエラーが発生します。
man ps
sh: bat: line 10: syntax error near unexpected token `('
sh: bat: line 10: ` *.?(ba)sh)'
sh: error importing function definition for `bat'
私の考えでは、いくつかのシェル(sh
)はBashismを迷惑にするようです。 Bash-ismsを以下から削除すると~/.bashrc
:
function bat {
# lines snipped for brevity
case "$f" in
*.rs ) opt_syntax="--syntax=rust";;
*.?(ba)sh ) opt_syntax="--syntax=shellscript";;
*.?(m)m ) opt_syntax="--syntax=objc";;
esac
# lines snipped for brevity
}
export -f bat
.bashrc
Bashの起動時にエラーや警告が表示されないため、それ自体に問題はないと確信しています。追加のデバッグを通じて.profile
購入したことがわかりました。.bashrc
# source Bash customizations
[ -n "${BASH_VERSION}" ] && [ -r "${HOME}/.bashrc" ] && . "${HOME}/.bashrc"
このように~/.bashrc
始めました。
# If not running interactively, don't do anything
[[ "$-" != *i* ]] && return
質問:
- なぜ始める前にリソースを確保する
man
必要がありますか?.profile
- 二重チェックにもかかわらず、上記のコードがBashではなくシェルで解析されるのはなぜですか?
- Bashではない場合、
.profile
ソースコードが得られないことを確認してください。.bashrc
.bashrc
さらに処理を中止するには、非対話式にチェックインしてください。
- Bashではない場合、
@muruのコメントを通して、Bashではなくシェルからインポートする危険があるので、エクスポートされた関数にBashismを含めてはいけないことに気づきました。残りの質問:なぜman
電話するのですsh
か?。
ベストアンサー1
man
あなたのものを読みませんが、いくつかのコマンドラインを解釈するために~/.profile
実行されます(または少なくとも私のシステムではスクリプトラッパーを解釈します)。そしてあなたのシステムでは:sh
nroff
sh
groff
sh
bash
輸入bash
export -f
(shellshockの後に名前付き変数から)BASH_FUNC_funcname%%
によってエクスポートされた関数、sh
。
extglob
ここでは、このオプションによって構文が異なる関数をエクスポートしています。したがって、実行sh
(モードbash
で)してエクスポートされたすべての機能をインポートすると、デフォルトで有効なオプション(モードであるかどうか)ではないsh
ため、問題を解決できません。extglob
sh
IOW、関数のエクスポートは、その関数がすべての呼び出しで使用されることを意味しますbash
。sh
したがって、sh
これらの関数の構文が-as-in-default設定と互換性があることにbash
注意する必要があります。それ以外の場合は、関数のエクスポートをすべて避ける必要があります。これらの関数が呼び出されなくても、これらの関数のコードも解析されます。bash
sh
bash
望むより:
$ env 'BASH_FUNC_f%%=() { case x in ?(x)) echo x; esac; }' bash -O extglob -c f
x
$ env 'BASH_FUNC_f%%=() { case x in ?(x)) echo x; esac; }' bash -c f
bash: f: line 0: syntax error near unexpected token `('
bash: f: line 0: `f () { case x in ?(x)) echo x; esac; }'
bash: error importing function definition for `f'
bash: line 1: f: command not found
関数にこのような解析に影響を与えるデフォルト以外のオプションが必要な場合は、extglob
次のように定義できます。
f() (
shopt -s extglob
eval '
function body here
'
)
export -f f
これは、オプションが関数の実行中にのみ設定されるようにサブシェルでコードを実行し(ローカル範囲を持たないbash
オプションzsh
またはオプション(最近のバージョンで設定されたオプションを除く)とは逆に)、関数が呼び出されるまで遅延解析を使用し、オプションが設定されますされました。ksh
set
eval
extglob
ここでも次のことができます。
f() (
shopt -s extglob
pattern='*.?(ba)sh'
case ... in
($pattern)...
esac
)
ただし、次のようにすることもできます。
f() {
case ... in
(*.sh | *.bash) ...
esac
}
これはsh
必要ありませんextglob
。