Я создал простую программу на C, например:
int main(int argc, char *argv[]) {
if (argc != 5) {
fputs("Not enough arguments!\n", stderr);
exit(EXIT_FAILURE);
}
И мой PATH был изменен в etc / bash.bashrc примерно так:
PATH=.:$PATH
Я сохранил эту программу как set.c и собираю ее
gcc -o set set.c
в папке
~/Programming/so
Тем не менее, когда я звоню
set 2 3
Ничего не произошло. Там нет текста, который появляется.
призвание
./set 2 3
дает ожидаемый результат
У меня никогда не было проблем с PATH раньше и
which set
возвращается ./set
. Так что, кажется, ПУТЬ правильный. Что происходит?
shell
path
shell-builtin
Ганея Дан Андрей
источник
источник
test
по той же причине;test
это встроенная оболочка тоже.test
имеет смысл. Конечно, к тому времени, когда вы положите это в свой,PATH
вы действительно должны были придумать другое имя. И пока вы не поместите программу в свою,PATH
вы должны будете вызывать ее так./test
или иначе. Поэтому вполне нормально использовать имяtest
для программы, если это быстрый тест, который вы собираетесь удалить до конца дня.foo
.ls
то всякий раз, когда вы будете проверять, существует ли он, он будет запускаться (но только если вы измените свой путь, как вы указали в вопросе).Ответы:
Вместо использования
which
, которое не работает, когда вам это нужно больше всего , используйтеtype
для определения того, что будет работать при вводе команды:Оболочка всегда ищет встроенные функции перед поиском
$PATH
, поэтому настройка$PATH
здесь не поможет.Лучше было бы переименовать ваш исполняемый файл во что-то другое, но если ваше назначение требует имени программы
set
, вы можете использовать функцию оболочки:(Это работает
bash
, но другие оболочки вродеksh
не могут этого позволить. См. Ответ mikeserv для более портативного решения.)Теперь при наборе текста
set
будет запущена функция с именем set./set
. GNUbash
ищет функции перед поиском встроенных функций и ищет встроенные функции перед поиском$PATH
. Раздел «КОМАНДНОЕ ИСПОЛНЕНИЕ» на странице руководства bash дает более подробную информацию об этом.Смотрите также документацию по
builtin
иcommand
:help builtin
иhelp command
.источник
type
болееwhich
, но не дают никаких оснований , почему. ( Я знаю почему , но тот, кому нужна рекомендация, не стал бы.)type
вместоwhich
, не называйте вашу программу "set", и поймите, чтоfunction set { ./set; }
это ужасный хак, которого вы, вероятно, должны избегать.set
является встроенным в Bash (и, вероятно, большинство других оболочек). Это означает, что bash даже не будет искать путь при поиске функции.В качестве дополнительного замечания я бы настоятельно рекомендовал не добавлять
.
путь в целях безопасности. Представьте, напримерcd
, что/tmp
после того, как любой другой пользователь добавил исполняемый файл/tmp/cd
.источник
cd
это встроенная оболочка, поэтому пример не будет работать по той же причине, что и сset
../foo
для вызова программы является профессиональным; это показывает, что вы понимаете, почему.
не должно быть в $ PATH. Ваш учитель не прав, и вы можете сказать ему, что я так сказал.set
это не просто встроенная функция, это специальная встроенная функция POSIX . Существует несколько встроенных команд, которые определены стандартами и которые можно найти в поиске команд раньше всего$PATH
: поиск не выполняется, имена функций не ищутся и т. Д. Большинство встроенных команд, которые не являются специальными , фактически требуются стандартом POSIX для находится в вашем$PATH
до того, как оболочка запустит любую из своих встроенных процедур. Это относитсяecho
и большинство других (хотя ли стандарт почитаются в этом отношении был предметом спора в открытых списках рассылки в прошлом) , но не изset
,trap
,break
,return
,continue
,.
,:
,times
,eval
,exit
,export
,readonly
,unset
, Илиexec
.Все они являются зарезервированными именами оболочки и имеют специальные атрибуты, отличные от порядка их предпочтения для поиска команд. Например, вы не можете определить функцию оболочки с любым из этих имен в стандартизированной оболочке. Это хорошо - это позволяет людям безопасно писать переносимые скрипты . Это базовые команды, из которых опытный сценарист может установить безопасную и надежную точку опоры в своей среде. Вторжение в это пространство имен не рекомендуется.
Однако, если вы хотите вторгнуться в него, вы можете сделать это с помощью
alias
. Порядок расширения оболочки позволяет это обойти. Поскольку воalias
время чтения команды оно раскрывается, то независимо от того, какое имя вы заменитеset
в своем определении, оно будет правильно развернуто, и, вероятно, оно не должно распространяться на одно из этих имен.Так что вы могли бы сделать:
... который будет работать просто отлично.
источник
Проблема в том, что
set
это встроенная оболочка, и лучшим решением будет использование другого имени для вашей исполняемой программы.Кстати, на прошлой неделе я задал вопрос о том, как запускать системные команды вместо встроенных команд с тем же именем, и решение, которое я принял, состояло в том, чтобы выполнить команду через
env
:Для этого конкретного случая, когда вы уже знаете, что команда, которую вы хотите использовать, находится в вашем текущем каталоге, было бы лучше напрямую запустить исполняемый файл, введя его путь (используя
.
для представления текущего рабочего каталога):Оба вышеупомянутых решения не зависят от оболочки, т. Е. Они будут работать независимо от того, какую оболочку вы используете.
Такие предложения, как использование
command
встроенной функции, не будут работать в Bash: это только предотвращает запуск функций оболочки . Хотя это не задокументировано, я также заметил, что использованиеcommand
также подавляет ключевые слова оболочки . Однако, это не будет делать то же самое для встроенных командных оболочек, таких какset
. Насколько я понимаю,command
могут работать другие оболочки, такие как zsh.Кроме того , приемы , такие как
\set
или"set"
или'set'
не работать на Bash встроенных команд - хотя они полезны для запуска исполняемых файлов вместо псевдонимов или оболочки ключевых слов .Примечание. Этот ответ изначально начинался как комментарий к принятому Эрику ответу, но стал слишком большим, чтобы вписаться в комментарий. Другие ответы, рекомендующие использование,
type
а не добавление.
к PATH, являются хорошими.источник