Исполняемый файл с именем ‘test’ находится в $PATH, но не запускается.

Вопрос или проблема

У меня есть файл в $HOME/bin (прежде чем вы спросите, да, он в моем пути) с именем test, который я подтвердил, что может быть выполнен без проблем, когда я запускаю его с полным путем к файлу. Однако у меня возникает очень странная проблема, когда я не запускаю его таким образом. Когда я просто ввожу test в терминале, он ничего не делает и сразу возвращается. Я знаю, что это не проблема нахождения файла по нескольким причинам:

  1. Нет сообщения об ошибке. Обычно, если файл не может быть найден или выполнен, появляется сообщение об этом.

  2. Команда which test все равно возвращает правильный путь к файлу.

  3. Наверное, самое странное – скрипт нормально работает, когда запускается через strace. Я попытался использовать strace, чтобы выяснить, что происходит, но когда я запустил его с strace, он работал как ожидалось без проблем.

test — это неудачное имя, его использование приводит к путанице, это стандартная утилита для условных тестов. (На самом деле, это та же команда, что и [ в if [ ... ], которая выглядит как синтаксическая конструкция, но на самом деле является обычной командой.)

test также встроена в, например, Bash, так что просто введя test, она никогда не ищет ваш бинарный файл в пути.

bash$ help test | head
test: test [expr]
    Оценить условное выражение.
    
    Завершает работу со статусом 0 (истина) или 1 (ложь) в зависимости от
    оценки EXPR.  Выражения могут быть унарными или бинарными.
    [...]

test без аргументов просто возвращает 1 (ложь).

Запуск strace test не задействует встроенную команду оболочки, так как strace не реализует никаких утилит самостоятельно. Он просто использует то, что находит в вашем PATH. Обратите внимание, что, вероятно, у вас есть стандартный test в /bin/test или /usr/bin/test, так что если он окажется первым в PATH, strace запустит его.

В моем Bash команда which также является внешней командой, так что она не знает о встроенных командах. С другой стороны, команда type встроена в оболочку, и type test покажет, что test is a shell builtin.

Смотрите также: Почему не использовать “which”? Что использовать тогда?

Ответ или решение

Проблема, с которой вы столкнулись, связана с тем, что имя вашего исполняемого файла test совпадает с именем стандартной утилиты test, которая является встроенной командой в оболочке Bash и, вероятно, в других оболочках. Вот подробный разбор ситуации и возможные пути её решения:

Описание проблемы

  1. Вызов встроенной команды: Когда вы просто вводите test в терминале, оболочка Bash не ищет исполняемый файл в вашем пути ($PATH), а вызывает встроенную команду test. Эта встроенная команда проверяет условные выражения и, если не переданы аргументы, возвращает код завершения 1 (что обозначает "ложь") и завершает выполнение.

  2. Работа с strace: Когда вы используете strace test, происходит вызов вашей программы, поскольку strace игнорирует встроенные команды и взаимодействует только с исполняемыми файлами. Именно поэтому ваш скрипт работает корректно при вызове через strace.

  3. Доступность команды: Использование команды which test также показывает путь к вашей программе, но это не учитывает встроенные команды, поэтому она не может указать на то, что test является встроенной командой в оболочке.

Решение проблемы

Чтобы избежать конфликта между вашим скриптом и встроенной командой test, вы можете сделать следующее:

  1. Измените имя вашего файла: Это самый простой и рекомендуемый метод. Переименуйте ваш скрипт в что-то более уникальное, например, mytest или run_test. Это гарантирует, что вы всегда будете вызывать именно вашу программу, а не встроенную команду.

  2. Запуск из абсолютного пути: Если вы хотите продолжать использовать имя test, вы можете запускать ваш скрипт с полным путём, например:

    $HOME/bin/test

    Однако это решение менее удобно, так как требует постоянного ввода полного пути.

  3. Использование другой оболочки: В некоторых случаях вы можете использовать другую оболочку, которая не имеет встроенной команды test, например, sh или dash, чтобы запустить ваш скрипт, но это не всегда может быть целесообразно.

Проверка идентификации

Чтобы проверить, является ли команда встроенной, вы можете использовать команду type:

type test

В результате выполнения этой команды вы увидите, что test является встроенной командой, тогда как путь к вашему исполняемому файлу не будет отображаться.

Заключение

Проблема, с которой вы столкнулись, была вызвана конфликтом имён с встроенной командой в оболочке Bash. Рекомендуемое решение — переименовать ваш исполняемый файл, что соответствует лучшим практикам программирования и помогает избежать подобных ситуаций в будущем.

Оцените материал
Добавить комментарий

Капча загружается...