Im Pfad ausführbar, von wem auffindbar, aber ohne vollständigen Pfad nicht ausführbar?


12

Ich habe ein bizarr anmutendes Shell-Problem mit einem Befehl im $ PATH, den die Shell (ksh, läuft unter Linux) scheinbar feige ablehnt, aufzurufen. Ohne den Befehl vollständig zu qualifizieren, erhalte ich:

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

aber die Datei kann gefunden werden, von denen:

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

Ich sehe das Verzeichnis auch explizit in $ PATH:

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

Die exe an diesem Ort scheint normal zu sein:

#  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

und wenn ich es explizit unter Verwendung eines vollqualifizierten Pfads ausführe:

#  /home/me/mydir/admbin/mycommand

Ich sehe die erwartete Ausgabe. Irgendetwas verwirrt die Shell hier definitiv, aber ich bin ratlos, was es sein könnte?

BEARBEITEN: Finden einer ähnlichen Frage: Binärdatei wird nicht ausgeführt, wenn sie mit einem Pfad ausgeführt wird. ZB> ./ Programm funktioniert nicht, aber> Programm funktioniert gut

Ich habe auch mehr als einen solchen Befehl in meinem $ PATH getestet, finde aber nur einen:

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

EDIT2:

Ab heute Morgen ist das Problem verschwunden und ich kann jetzt die ausführbare Datei ausführen.

Das könnte als Bestätigung des Vorschlags zum Abmelden und Anmelden angesehen werden, aber das hatte ich letzte Nacht ohne Erfolg getan. Dieses Abmelden / Anmelden hätte auch das Äquivalent zum Ausführen des vorgeschlagenen Befehls 'hash -r' sein müssen (bei dem es sich anscheinend auch um ein ksh-Builtin und nicht nur um ein bash-Builtin handelt).

Als Antwort auf einige der Antworten:

  • Dies ist eine ausführbare Datei, kein Skript (siehe ELF-Referenz in der Ausgabe des Dateibefehls).

  • Ich glaube nicht, dass eine Strace geholfen hätte. Das führt dazu, dass der Befehl gezwungen wird, vollständig qualifiziert auszuführen. Ich nehme an, ich hätte die aktuelle Shell strace attach machen können, aber da ich keine Reproduktion mehr machen kann, ist es sinnlos, das zu versuchen.

  • Im $ PATH waren keine Semikolons. Da ich keinen Repro mehr machen kann, werde ich diese Frage nicht mit dem vollen $ PATH überladen.

  • es wäre etwas gewesen, das ich auch versucht hätte, wie vorgeschlagen wurde, eine andere Shell (dh Bash) zu versuchen. Wenn das Problem weg ist, weiß ich jetzt nicht, ob das geholfen hätte.

Es wurde mir auch vorgeschlagen, die Verzeichnisberechtigungen zu überprüfen. Dabei sehe ich für jedes der Verzeichnisse bis zu diesem:

# 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

Der Besitz des $ HOME-Verzeichnisses ist durcheinander (sollte keine Stammgruppe sein). Das könnte andere Probleme verursachen, aber ich sehe nicht ein, wie es dieses verursacht hätte.


2
Dein Scripting-Kung-Fu ist fantastisch.
Jeff Ferland

2
Ich weiß, das klingt zu simpel, aber ich hatte einmal das gleiche Problem und es stellte sich heraus, dass es sich um ein Semikolon handelte, das anstelle eines Doppelpunkts als Pfadtrennzeichen verwendet wurde.
John Gardeniers

Können Sie Ihre gesamte PATH-Einstellung angeben?
Jason Huntley

Dies ist eine hervorragend geschriebene Frage.
gWaldo

könnte das Caching der Shell gewesen sein?
Michael Slade

Antworten:


1

Wahrscheinlich müssen Sie den Cache Ihrer Shell mit den Elementen aktualisieren, die Sie $PATHverwenden hash -r.


$ apropos hash | grep ksh-- nichts. Sie haben mit einem basheingebauten Code geantwortet , aber das ist nicht die fragliche Shell.
Jeff Ferland

1

Überprüfen Sie in solchen Fällen auch, was passiert, wenn das Programm aufgerufen wird, indem Sie seine ausführbare Datei als Argument an den dynamischen Linker übergeben (dies wird möglicherweise abgelehnt, während setuid / setgid auf einigen Systemen verwendet wird).

Die Ausgabe von ldd (1) in beiden Fällen könnte ebenfalls aufschlussreich sein. "Keine solche Datei oder kein solches Verzeichnis" in einer ausführbaren Datei bedeutet, dass der in der ausführbaren Datei angegebene dynamische Linker nicht gefunden werden kann.

Dieses Verhalten hatte Leute verblüfft, die Zeuge des Endes der libc5-Ära waren, und jetzt gelegentlich verblüffte Leute in der Ära von gemischtem i386 / amd64 mit unterschiedlichen Mitteln, um zwei Bibliothekssätze in freier Wildbahn zu unterstützen.

Relativer RPATH in der ausführbaren Datei im Vergleich zu $ ​​PWD?

PS Die andere Frage bezieht sich auf MacOSX, das wahrscheinlich dyld und nicht den von libc bereitgestellten Linker verwendet. Ganz andere Tierart.


0

Okay, ich habe keine Antwort. Ich habe ein paar Dinge bewiesen und denke, dass ich später noch hinzufügen kann:

  • Erstellt ein Testfile - Ihre Berechtigungen zeigen, dass es setuid und ausführbar ist.
  • Versucht, es auf einem Einhängepunkt mit nosuid zu setzen: läuft noch
  • Versucht es auf einem Mount-Punkt mit noexec zu setzen: gibt einen anderen Fehler aus

Ich bin also nach wie vor genauso verwirrt. Nur zum Grinsen und gelegentlich handelt es sich um einen Fehler, der mit der Shell zusammenhängt. Können Sie es mit einer anderen Shell versuchen?


0

Ich vermute, dass Ihr Skript nach dem #! Keine gültige Shell hat. Beispielsweise funktionieren auf einigen älteren SCO-Systemen Skripts mit #! / Bin / bash nicht, da bash WIRKLICH in / usr / bin / bash enthalten ist. Dumm, aber hey SCO ist aus einem bestimmten Grund fast tot, oder?

Überprüfen Sie Ihre Shell und vergewissern Sie sich, dass sie auf eine echte Binärdatei / ein echtes Skript verweist.

Bearbeiten: Es sagt nicht, ob es sich um ein Skript oder eine Binärdatei handelt, aber wenn die Ausgabe von 'ls -l' korrekt ist, haben Sie wahrscheinlich kein 93-KByte-Skript ... das ist also wahrscheinlich eine Binärdatei, was meine Antwort bedeutet total falsch.

Haben Sie versucht, sich aus- und wieder einzuloggen? Ich weiß, wenn ich eine Binärdatei verwende, die sich in / usr / bin befindet, dann installiere ich eine / usr / local / bin-Version von der Quelle. Das System versucht immer noch, die Originalversion auszuführen, bis ich mich aus- und wieder einlogge.


Es war eine ausführbare Datei und kein Skript (siehe die ELF-Informationen aus der Datei in der Frage). Ja, ich hatte mich
aus-

0

Meine Vermutungen:

  • Sie hatten einen Aliasnamen mycommand. Beispielsweise:

    alias mycommand=something
    
  • Sie hatten eine Funktion mit dem Namen mycommand. Beispielsweise:

    mycommand() { something; }
    

Wenn Sie das nächste Mal auf dieses Problem stoßen, versuchen Sie es mit dem Ausführen, um festzustellen, command -V mycommandfür welche Art von Befehl die Shell mycommandsteht.


Keines davon war bei diesem Befehl der Fall.
Peeter Joot

0

Keine Antwort, nur ein paar Gedanken:

  1. Überprüfen Sie, ob der Dateiname Leerzeichen enthält. Dies wird unbemerkt ignoriert, wenn die Tab-Vervollständigung verwendet und als Parameter verwendet wird.
  2. Versuchen Sie es mit einem anderen Skript / Programm im Verzeichnis.
  3. Versuchen Sie, die Shell zu stracen, indem Sie versuchen, das Skript auszuführen und festzustellen, wo es bricht.

0

Ich hatte genau das gleiche Problem und konnte keine Antwort finden, da sich das Problem des ursprünglichen Posters von selbst löste. Aber das hat bei mir nicht funktioniert und ich habe es endlich geschafft, das Problem aufzuspüren. Daher füge ich Folgendes als Antwort auf den ursprünglichen Beitrag hinzu.

Die Symptome, mit denen ich konfrontiert war, waren die folgenden. Es gibt ein Skript (myscript.pl) im Verzeichnis / my / home. Versuchen Sie nun, es auszuführen:

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

Verifizierte Berechtigung der Datei (Ausführungsflag gesetzt). Verifizierter $ PATH (obwohl es kein Problem geben sollte).

Also versuche ich (nachdem ich überprüft habe, ob das Flag für die ausführbare Datei im Skript gesetzt ist):

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

Hmmm ... Vielleicht ruft das Skript nicht die richtige Skriptsprache auf (in diesem Fall Perl). Die Spitze des Skripts hat die richtige Magie:

#!/usr/bin/perl

und tatsächlich existiert / usr / bin / perl und funktioniert. Der folgende Aufruf funktioniert also korrekt.

/usr/bin/perl myscript.pl

Die Registerkarte Auto-Vervollständigung zeigt die Datei nicht an (weder in tcshnoch in bash).

Das hat mich wirklich umgehauen. Dann erinnerte ich mich, dass vor ein paar Monaten meine Festplatte abgestürzt ist und der junge Systemadministrator in meinem Labor das System neu installiert hat. Dachte, er hätte die Berechtigungen für die Partitionen vermasselt. Und in der Tat /etc/fstabfehlte die exec-Berechtigung!

/dev/sda1    /my     /ext4      rw,user

Anstatt von

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

Dies wurde durch Ändern /etc/fstabund erneutes Einhängen behoben:

mount -v -o remount /my

Dies löste das Problem vollständig. Ich vermute, dass ein ähnliches Problem mit dem Problem des ursprünglichen Posters aufgetreten ist, mit der Ausnahme, dass das Berechtigungsproblem zeitweise aufgetreten ist (z. B. gab es eine vorübergehende Änderung, die möglicherweise durch einen Neustart behoben wurde, falls einer stattfand).


-1

Keine vollständige Antwort, wollte aber über meine Erfahrungen berichten, da ich genau das gleiche Problem hatte wie der Fragesteller, und dachte, es könnte zukünftigen Benutzern helfen, die das gleiche verrückte Problem haben. Ich könnte die Datei waschen und sie in meinem Pfad sehen und sie sogar unter Angabe des vollständigen Pfades ausführen, aber nicht anders ausführen. In meinem Fall passierte dies jedoch nur innerhalb einer Sub-Shell (dh als es von einem Skript ausgeführt wurde, gab es in diesem Fall einige verschachtelte Sub-Shells). Ich könnte es von der Kommandozeile aus gut laufen lassen.

Kurz vor dem Befehl im verschachtelten Skript habe ich den Befehl ausgedruckt, zB echo $ (welcher mein Befehl)

meinebefehl: / home / ich / bin / meinebefehl

Dann würde ich versuchen, es aus dem übergeordneten Skript auszuführen:

/ home / me / bin / some_parent_script [72]: mycommand: not found [Keine solche Datei oder kein solches Verzeichnis]

Genau wie der Fragesteller konnte ich die Ursache des Problems nicht diagnostizieren. Mein PFAD sah richtig aus, es war was-fähig, und Hash enthüllte keine vorherigen Einträge von mycommand. Am nächsten Tag, als ich mich einloggte, funktionierte alles wieder auf magische Weise. Jetzt werde ich hier bemerken, dass ein bekanntes Systemproblem aufgetreten ist, kurz bevor ich dieses Problem sah, bei dem ein Mount erneut gemountet wurde. Vielleicht ist das ein Hinweis?

Wenn ich keine Protokolldatei nach der Protokolldatei hätte, die zeigt, dass dies geschehen ist, würde ich nicht glauben, dass es möglich gewesen wäre! Dank des Fragestellers fühle ich mich nicht mehr verrückt!

PS Ich glaube nicht, dass user226160 das gleiche Problem hatte wie der Reporter, aber es klingt verwandt und verleiht der Mount-Theorie Glaubwürdigkeit.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.