Почему встроенные функции Shell нельзя запускать заглавными буквами, а другие команды?

33

Почему это?

Когда я делаю это

CD ~/Desktop

Это не берет меня на рабочий стол. Но это:

echo "foo
bar" | GREP bar

дает мне:

bar
Отображаемое имя
источник
4
Проверьте, если alias GREPили which GREPвыводите что-нибудь
chepner
1
Вот и ты. У вас есть команда с именем GREP, которая отличается от grep. (Правда, это может быть просто жесткая ссылка или символическая ссылка на /usr/bin/grepнее, но с точки зрения оболочки это отдельная команда.)
chepner
12
Подождите, вы на Mac OS X, не так ли? HFS + сохраняет регистр по умолчанию, что означает, что если регистр имеет значение, когда вы создаете файл, но как только файл существует, поиск выполняется без учета регистра. То есть bashможет запрашивать файл с именем GREP, но файловая система считает grepсовпадение.
chepner
1
Да, потому что это Unix.
DisplayName
4
Файловые системы не зависят от операционной системы. Вы можете использовать другие файловые системы с Mac OS X, и вы можете (теоретически) использовать HFS + с другими операционными системами. Также вы можете сделать HFS + чувствительным к регистру; сохраняющее регистр поведение - просто значение по умолчанию по историческим причинам.
Chepner

Ответы:

71

Из ваших других вопросов я понимаю, что вы используете OS X. В файловой системе HFS + по умолчанию в OS X регистр не учитывается: у вас не может быть двух файлов с именами «abc» и «ABC» в одном каталоге, и вы пытаетесь получить доступ к ним. любое имя попадет в тот же файл. То же самое может произойти в Cygwin или с нечувствительными к регистру файловыми системами (такими как FAT32 или ciopfs ) где угодно.

Поскольку grepэто настоящий исполняемый файл, он был найден в файловой системе (в каталогах PATH). Когда ваша оболочка выглядит в /usr/binтечение либо grepили GREPон будет найти grepисполняемый файл.

Встроенные в оболочку не ищутся в файловой системе: поскольку они встроены, они доступны через (с учетом регистра) сравнения строк внутри самой оболочки.

То, с чем вы сталкиваетесь, - интересный случай. В то время как cdявляется встроенным, доступ к нему с учетом регистра, CDнаходится в качестве исполняемого файла /usr/bin/cd. cdИсполняемое довольно бесполезно: потому что cdвлияет на текущую среду выполнения оболочки, она всегда предоставляются в качестве оболочки обычного встроенных , но есть cdисполняемый ради Posix в любом случае, который изменяет каталог для себя , а затем сразу же заканчивается, оставляя окружающую оболочку где это началось

Вы можете попробовать это с помощью typeвстроенного :

$ type cd
cd is a shell builtin
$ type CD
CD is /usr/bin/CD

typeговорит вам, что будет делать оболочка при запуске этой команды. При запуске cdвы получаете доступ к встроенному, но находите CDисполняемый файл. Для других встроенных функций встроенный модуль и исполняемый файл будут разумно совместимы (попробуйте echo), но cdэто невозможно.

Майкл Гомер
источник
1
хороший ответ Я собирался сказать Cygwin, что будет иметь тот же эффект.
Джошуа
@ Joshua Проблема ОП решена, но я думаю, что для дальнейших читателей вопроса ответ на основе Cygwin будет, по крайней мере, таким же полезным, как и существующий; Может быть, вы можете сделать это отдельным ответом, пусть даже коротким, и перенести его на существующий для деталей?
Фолькер Сигел
1
Почему posix требует бесполезной команды, такой как cd, и почему внутренний cd в osx не подходит?
Джон
2
51 голосов! Я должен был просто опубликовать ответ, а не комментарий :)
chepner
1
/ usr / bin / cd имеет цель. синтаксис / usr / bin / cd
Джошуа