Исполняемый по пути, который можно найти, но который не может быть выполнен без полного пути?

У меня странная проблема с оболочкой, с командой в $PATH, что оболочка (ksh, работающая в Linux) трусливо отказывается вызывать. Без полной квалификации команды я получаю:

#  mycommand
/bin/ksh: mycommand: not found [No such file or directory]

но файл может быть найден с помощью которого:

#  which mycommand
/home/me/mydir/admbin/mycommand

Я также явно вижу этот каталог в $ PATH:

#  echo $PATH | tr : '\n' | grep adm
/home/me/mydir/admbin

Exe в этом месте кажется нормальным:

#  file /home/me/mydir/admbin/mycommand
/home/me/mydir/admbin/mycommand: setuid setgid ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.4, dynamically linked (uses shared libs), not stripped

# ls -l mycommand  
-r-sr-s--- 1 me mygroup 97892 2012-04-11 18:01 mycommand

и если я запускаю его явно, используя полный путь:

#  /home/me/mydir/admbin/mycommand

Я вижу ожидаемый результат. Что-то определенно запутывает оболочку здесь, но я в недоумении, что это может быть?

РЕДАКТИРОВАТЬ: найти что-то похожее на вопрос: двоичный файл не будет выполняться при запуске с путем. Например>./ программа не будет работать, но> программа работает нормально

Я также протестировал более одной такой команды в моем $PATH, но нашел только одну:

# for i in `echo $PATH | tr : '\n'` ; do test -e $i/mycommand && echo $i/mycommand ; done
/home/me/mydir/admbin/mycommand

EDIT2:

По состоянию на это утро проблема исчезла, и теперь я могу выполнить исполняемый файл.

Это можно рассматривать как подтверждение предложения выйти из системы и войти в систему, но я сделал это прошлой ночью безуспешно. Этот выход из системы / вход в систему должен был также выполнить команду "hash -r", которая была предложена (которая, по-видимому, также является встроенной в ksh, а не просто встроенной в bash).

В ответ на некоторые ответы:

  • Это исполняемый файл, а не скрипт (см. Ссылку на ELF в выходных данных команды file).

  • Я не думаю, что это помогло бы. Это приводит к принудительному выполнению команды. Я полагаю, что я мог бы сделать прямое присоединение к текущей оболочке, но, поскольку я больше не могу воспроизводить, нет смысла пытаться это сделать.

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

  • Попробовать другую оболочку (например, bash) я бы тоже попробовал, как и было предложено. Когда проблема исчезла, я не знаю, помогло бы это.

Также было предложено мне проверить права доступа к каталогу. При этом для каждого из каталогов до этого я вижу:

# ls -ld $HOME $HOME/mydir $HOME/mydir/admbin
drwxr-xr-x 10 me root    4096 2012-04-12 12:20 /home/me
drwxrwsr-t 22 me mygroup 4096 2012-04-12 12:04 /home/me/mydir
drwxr-sr-x  2 me mygroup 4096 2012-04-12 12:04 /home/me/mydir/admbin

Владение каталогом $HOME испорчено (не должно быть корневой группой). Это может вызвать другие проблемы, но я не понимаю, как это могло бы вызвать это.

8 ответов

Возможно, вам нужно обновить кеш элементов вашей оболочки $PATH с помощью hash -r,

Кроме того, в таких случаях проверьте, что происходит, когда программа вызывается, передавая свой исполняемый файл в качестве аргумента динамическому компоновщику (может отказать в этом, пока setuid/setgid в некоторых системах).

Вывод ldd(1) в обоих случаях также может быть показательным. "Нет такого файла или каталога" в исполняемом файле действительно означает, что динамический компоновщик, указанный в исполняемом файле, не может быть найден (представьте, что исполняемый файл имеет форму ELFin #!/lib/ld-linux.what.so.ever.ever внутри)

В результате такого поведения люди были ошарашены тем, что были свидетелями окончания эры libc5, а теперь время от времени ошеломляют людей в эпоху смешанного i386/amd64 с различными средствами поддержки двух наборов библиотек в дикой природе.

Относительный RPATH в исполняемом файле против $ PWD?

PS другой вопрос связан с MacOSX, который, вероятно, использует dyld, а не предоставленный libc компоновщик. Очень разные виды животных.

У меня была точно такая же проблема, и я не смог найти ответ, потому что проблема оригинального плаката разрешилась сама собой. Но это не сработало для меня, и мне наконец удалось отследить проблему. Поэтому я добавляю следующее как ответ на оригинальный пост.

Симптомы, с которыми я столкнулся, были следующие. В каталоге /my/home есть скрипт (myscript.pl). Теперь пытаюсь запустить его:

> /my/home/myscript.pl
myscript.pl:  permission denied.

Проверено разрешение файла (установлен флаг выполнения). Проверено $PATH (хотя проблем не должно быть).

Итак, я пытаюсь (после проверки, что исполняемый флаг установлен в сценарии):

> cd /my/home/
> ./myscript.pl:  permission denied.

Хммм... Так что, возможно, скрипт не вызывает правильный язык сценариев (в данном случае perl). Вершина скрипта имеет правильную магию:

#!/usr/bin/perl

и действительно / usr / bin / perl существует и работает. Таким образом, следующий вызов работает правильно.

/usr/bin/perl myscript.pl

вкладка автозаполнения не будет показывать файл (ни в tcsh ни в bash).

Это действительно сбило меня с толку. Потом вспомнил, что несколько месяцев назад мой жесткий диск сломался, и молодой системный администратор в моей лаборатории переустановил систему. Думал, что он мог испортить разрешения на разделы. И действительно, в /etc/fstab, исполнительное разрешение отсутствовало!

/dev/sda1    /my     /ext4      rw,user

Вместо

/dev/sda1    /my     /ext4      rw,user,exec

Исправлено путем изменения /etc/fstab и перемонтирование:

mount -v -o remount /my

Это решило проблему полностью. Я предполагаю, что подобное могло произойти и с проблемой оригинального плаката, за исключением того, что проблема с разрешением была прерывистой (например, было временное изменение, которое могло бы быть решено перезагрузкой, если бы она произошла).

Мои догадки:

  • У вас был псевдоним mycommand, Например:

    alias mycommand=something
    
  • У вас была функция с именем mycommand, Например:

    mycommand() { something; }
    

В следующий раз, когда у вас возникнет эта проблема, попробуйте запустить command -V mycommand чтобы увидеть, в какую команду верит оболочка mycommand является.

Хорошо, у меня нет ответа. Я доказал несколько вещей и думаю, что могу добавить к этому позже:

  • Создан тестовый файл - ваши разрешения показывают, что он установлен и исполняемый.
  • Попробовал установить его в точке монтирования с помощью nosuid: все еще работает
  • Пробовал установить его на точку монтирования с помощью noexec: выдает другую ошибку

Так что, судя по всему, я все еще в замешательстве. Просто ради ухмылки и по случайности это ошибка, связанная с оболочкой, вы можете попробовать ее с другой оболочкой?

Я предполагаю, что ваш скрипт не имеет корректной оболочки после #!. Например, в некоторых старых системах SCO скрипты с #!/ Bin / bash не работают, потому что bash действительно живет в / usr / bin / bash. Тупой, но эй, ШОС почти мертва по причине, нет?

Проверьте вашу оболочку и убедитесь, что она указывает на настоящий двоичный файл / скрипт.

Edit: It doesn't tell if it's a script or a binary, but assuming your 'ls -l' output is correct, then you probably don't have a 93kbyte script... so this is probably a binary meaning my answer is totally incorrect.

Have you tried logging out and back in? I know if I use a binary that's in /usr/bin then install a /usr/local/bin version from source, the system still tries to execute the original one until I log out and back in.

Нет ответа, просто куча мыслей:

  1. Проверьте, содержит ли имя файла пробел; это незаметно игнорируется при использовании табуляции и использования в качестве параметра.
  2. Попробуйте другой скрипт / программу в каталоге.
  3. Попробуйте связать оболочку, пытаясь выполнить скрипт, и посмотрите, где он сломается.

Не полный ответ, но я хотел сообщить о своем опыте, поскольку у меня была та же проблема, что и у спрашивающего, и я подумал, что это может помочь будущим пользователям, столкнувшимся с такой же сводящей с ума проблемой. Я мог найти файл и увидеть его в моем пути, и даже выполнить его, указав полный путь, но не смог выполнить его иначе. Однако в моем случае это происходило только внутри вложенной оболочки (т. Е. Когда она выполнялась из скрипта, в этом случае было несколько вложенных вложенных оболочек). Я мог бы запустить его из командной строки просто отлично.

Непосредственно перед командой во вложенном скрипте я распечатал команду, например, echo $(которая mycommand)

mycommand: / home / me / bin / mycommand

Затем я бы попытался выполнить его из родительского скрипта:

/ home / me / bin / some_parent_script [72]: mycommand: not found [Нет такого файла или каталога]

Как и спрашивающий, я не смог определить причину проблемы. Мой PATH выглядел правильно, он был в состоянии, и хэш не выявил каких-либо предыдущих записей моей команды. На следующий день, когда я вошел в систему, все снова волшебным образом сработало. Теперь я отмечу здесь, что была известная системная проблема, которая произошла как раз перед тем, как я увидел эту проблему, где монтирование было перемонтировано. Может быть, это ключ?

Если бы у меня не было файла журнала после файла журнала, демонстрирующего, что это произошло, я бы не поверил, что это было возможно! Благодаря спрашивающему я больше не чувствую себя сумасшедшим!

PS Я не думаю, что у user226160 была ТОЧНАЯ та же проблема, что и у репортера, но это звучит по-своему и придает достоверность теории монтирования.

Другие вопросы по тегам