Readline関数Shell-expand-line
とalias-expand-line
をいじっていました。 ドキュメント から:
Shell-expand-lineシェルと同じように行を展開します。これは、エイリアスと履歴の展開、およびすべてのシェルワードの展開を実行します( シェルの展開を参照 )。
これについての私の理解は、Shell-expand-line
が実際の実行の前にbashが行うすべての置換と展開を実行するということです。
不自然な例がこれをサポートしているようです:
$ NAME="Adam"
$ alias ec='echo'
$ ec $NAME
関数Shell-expand-line
を実行すると、前のコマンドは$ echo Adam
に展開されます。
私の混乱が始まるのは、次の例です。
$ alias cdspace='cd ~/path\ with\ spaces'
$ cdspace
Shell-expand-line
を実行するかどうかの私の理解に基づいて、コマンドは$ cd /Users/Adam/path\ with\ spaces
に拡張されます。ただし、実際には$ cd ~/path with spaces
に展開されます。 cdspace
をそのまま、またはalias-expand-line
で実行すると期待どおりに動作しますが、Shell-expand-line
で展開すると、実行が失敗します。
Shell Expansions のサブセクション Quote Removal はこれに対処します:
上記の展開の後、上記の展開のいずれかによるものではない、文字「\」、「 '」、および「」の引用符で囲まれていないすべての出現が削除されます。
したがって、引用符で囲まれていないバックスラッシュは常に削除されるようです。これをテストするには、$ cd ~/path\ with\ spaces
を手動で入力してShell-expand-line
を実行すると、コマンドが$ cd ~/path with spaces
に更新されます。さらに、$ cd ~/path\\ with\\ spaces
と入力してからShell-expand-line
を2回実行すると、1組のバックスラッシュが削除されます。
私の予想では、Shell-expand-line
は、bashによって最終的に内部的に解決される行まで完全に拡張しますが、複数回実行する必要があるため、そうではないようです。
私が最終的に混乱しているのは、_ Shell Expansionsのドキュメント を理解しているように、$ cd ~/path\ with\ spaces
が正しく実行される方法です。最終的には$ cd ~/path with spaces
に解決されます。
ここではbashのドキュメントは不明確だと思います。別のコメントで述べたように、Shell-expand-line
ドキュメントは、チルダ展開が明確に行われていない場合にallシェル展開が実行されることを示唆しています。
さらに、引用の削除手順では、最初のセットがパターンマッチングされた後も残っている引用符で囲まれていないバックスラッシュは削除されません。これは、3.5.9( )とは異なり、https://www.gnu.org/savannah-checkouts/ gnu/bash/manual/bash.html#Quote-Removal )が示します。
とはいえ、私はそうは思いませんShell-expand-line
は、シェルから実行できるコマンドを生成することを目的としています。入力がalreadyにトークン化されていることを前提とするすべてのシェル拡張を実行しているため、パターンマッチングステップではバックスラッシュが削除され、以前にエスケープされたスペースが「エスケープ解除」されます。結果の文字列を実行しようとすると、トークン化againとなり、スペースで区切られた各Wordは個別のトークンとして扱われます。