ZSHでは、..
はcd ..
のおかげでauto_cd
と同等です。これは、推測する必要がある場合(完全に推測しています)、ある種のエイリアスです。
ただし、他の多くの*sh
'es(ash
、少なくともbash
)では、この機能は実装されていません。
ash
では、
willard@willardsworld:~/.ssh# ..
-ash: ..: Permission denied
これは奇抜です。 root
がディレクトリを所有しているため、推測する必要がある場合(ここでも推測)、アクセス許可エラーです。
willard@willardsworld:~/.ssh# ls -la
drwxr-xr-x 3 root root 4096 May 22 16:06 .
drwxr-xr-x 21 root root 4096 May 22 15:03 ..
drwx------ 2 root root 4096 May 26 11:37 .ssh
ただし、それでもroot
としては機能しません。
root@willardsworld:~/.ssh# ..
-ash: ..: Permission denied
これもまた、奇抜です。 root
は..
を所有していますよね?
この動作をbash
と比較してください。
willard@willardsworld:~/.ssh$ ..
..: command not found
これは完全に理にかなっています。その機能は存在しません。
私が疑問に思っているのは、ZSH auto_cd
はどのように機能し、なぜash
は許可エラーを吐き出すのですか?
これは原因についての知識に基づいた推測にすぎませんが、ここで何が起こっているのかを説明します。 「/
」を含まないコマンド名を使用すると(つまり、明示的なパスではなく単なる名前である)、シェルはそれがエイリアス、関数、または組み込みであるかどうか、およびそれがであるかどうかを確認します$PATH
のディレクトリで実行可能ファイルとして検索するものはありません。したがって、プロセスは次のようになります。
「..
」がエイリアス、関数、または組み込みであるかどうかを確認してください:いいえ。
$PATH
の最初のディレクトリが/bin
であるとします。 /bin/..
がファイルシステムに存在するかどうかを確認します:はい、存在します!
すべてのディレクトリには、ファイルシステム内の親ディレクトリへのリンクである「..
」という名前のアイテムが含まれているため、/bin/..
は/
へのリンクです。
/bin/..
を実行してみてください。これは、実行可能ファイルではなくディレクトリであるため失敗します。 (ディレクトリにcd
することはできますが、それを実行することとはまったく異なります。)
さて、これは、ある種の「実行可能ファイルではありません」エラーではなく「アクセス許可が拒否されました」エラーが発生する理由を説明していないので、私は間違っている可能性があります。 OSのash
で、明示的なコマンドとして/bin/..
を実行してみて、どのようなエラーメッセージが表示されるかを確認してください。
Bashは、「..」がディレクトリであることを識別し、実行を拒否する防御プログラミングを使用している必要があります。 ashは、execve(2)などを呼び出して、結果として生じるオペレーティングシステムエラーを返します。次の3行のCは、「許可が拒否されました」を出力します。
char *args[] = { "..", 0 };
execve("..", args, 0);
perror(0);
Execve(2)のマニュアルページには、EACCESの多くの解釈がリストされています。
Zsh機能はエイリアスとして実装されていません。エイリアス拡張は非常に早い段階で適用されます。これは、実行可能ファイルの検索とともに発生します。そして、あなたがするならunsetopt autocd
、「許可が拒否されました」と出力されます。