shopt
Zshで代わりに使用しようとしているときに思い出させるために、setopt
次のエイリアスを作成し、まずシェルプロンプトでテストしました。
$ alias shopt='echo "You\'re looking for setopt. This is Z shell, man, not Bash."'
外部一重引用符が内部二重引用符と一致し、アポストロフィがエスケープされていますが、次を使用して閉じる引用符を完成するように求められます。
dquote > _
どうなりますか?
エスケープが無視されているか、複数のレイヤーの解釈のためにデュアルエスケープが必要なようです...だから、この理論をテストするために、次のようにデュアルエスケープ(およびトリプルエスケープなど)を試しました。
alias shopt='echo "You\\\\\\\\\\\\\\\\\\\\\\'re looking for setopt. This is Z shell, man, not Bash." '
そしていいえ他の動作を確認してください。これは私には理解できません。どのような奇妙な魔法がシェルが私が期待したように動作するのを防ぎますか?
実際の解決策は、echo
実際には何も必要としないため、引用符を使用せずに二重引用符を使用し、テキストを編集するときに無視されるalias
ようにアポストロフィをエスケープすることです。echo
それではみんな実際問題は消えます。
助けてください?この混乱した問題を解決する必要があります。
答え1
これでzsh
はないfish
。
zsh
(とで)csh
すべてのBourneのようなシェルのように一重引用符は、エスケープのない強い引用符です。(rcquotes
以下のオプションを使用しない限り@JdeBP ヒント引用符1)をzsh
シミュレートしますrc
。一重引用符で囲まれた文字列の中に一重引用符を使用することはできません。まず、一重引用符で囲まれた文字列を閉じ、別の引用メカニズム(\
または)を使用して"
リテラル一重引用符を入力する必要があります。
alias shopt='echo "You'\''re looking for setopt. This is Z shell, man, not Bash."'
または:
alias shopt='echo "You'"'"'re looking for setopt. This is Z shell, man, not Bash."'
次のようにすることもできます。
alias shopt="echo \"You're looking for setopt. This is Z shell, man, not Bash.\""
("..."
はい弱い\
(ここでは埋め込み文字をエスケープするために使用されます)を含む引用符の中のいくつかの文字は"
まだ特別です。
または:
alias shopt=$'echo "You\'re looking for setopt. This is Z shell, man, not Bash."'
(エスケープできる$'...'
ksh93への別の参照)'
\'
(BTW、in.のset -o
代わりに標準を使用することもできます。歴史的な理由から、2つのオプションセットがあります。1つは設定用です。他のほとんどのシェルと同様に、オプションセットは1つだけです。setopt
zsh
bash
set -o
shopt
zsh
1 `rc`では、Plan9シェルにはUnixに似たバージョンもあります。 [一重引用符が唯一の引用メカニズムです](/a/296147)(バックスラッシュと二重引用符は一般的な文字です)、唯一の方法はEnter literal Singleです。 rcquotes"を使用すると、次のようにできます。
alias shopt = 'echo "setoptを探しています。これはBashではなくZシェルです。"'
答え2
shopt='エコ「あなた」
これは魔法ではありません。これは一般的なPOSIXシェル引用操作です。 一重引用符で囲まれた文字列にはエスケープメカニズムはありません。。常に次の単一引用符で終わります。 2つの連続した一重引用符文字列の間に一重引用符を挿入するZシェル拡張があります。これを使用できます。あるいは、一重引用符で囲まれた文字列を終了し、エスケープされた(または実際には一重引用符ではなく)一重引用符を使用してから、二重引用符で囲まれた文字列を開始することもできます。
または、メッセージに省略形を使用することはできません。 ☺
追加読書
答え3
他の答えは、これらの動作が現れる理由を非常によく説明しています。ただし、実際にこの問題を解決する方法を提案できる場合は、次のようにします。
非常に複雑な場合でもエイリアスを使用しないでください。
私はあなたを信じていますできるNレベルの引用符を入れ子にする方法を理解しようとすると、面倒なことになるかもしれませんが、エイリアシングにはそれほど価値はありません。エイリアスが複雑すぎて参照が重要になったら、シェル関数に切り替えます。
shopt(){
echo "You're looking for setopt. This is Z shell, man, not Bash."
}
これにより、引用符全体のレイヤーが削除され、後でシェル関数にさらにコードを追加でき、通常は読みやすくなります。また、「行の先頭を置き換えて、可能であれば残りの単語を配置する」エイリアスアプローチよりも、引数の挿入方法と位置をより細かく制御できます。たとえば、(変更された)エイリアスに次のように入力した場合:
shopt -s some_opt
...これにより、次の出力が表示されます。
You're looking for setopt. This is Z shell, man, not Bash. -s some_opt
これはあなたが望むものではないかもしれません。シェル関数は渡されたすべての引数を使用し、自動的に削除します。
答え4
今は削除されたコメントで答えを見つけるためのヒントを得ました。
一重引用符を外すことはできません。一重引用符文字列内。
最終的な解決策では、二重引用符で囲まれた文字列内の一重引用符を確実にエスケープしたため、二重引用符で囲まれた文字列にはこの制限はありません。
alias shopt="echo You\'re looking for setopt. This is Z shell, man, not Bash."