comando realpath non trovato


24

Ho debian squeeze amd64. La mia shell attuale è bash. Se scrivo quanto segue nel mio terminale, funziona:

$ uname -a
Linux core 2.6.32-5-amd64 #1 SMP Fri May 10 08:43:19 UTC 2013 x86_64 GNU/Linux
$ echo $SHELL
/bin/bash                                                                                                                                                                                     
$ echo $(realpath test.sh)                                                                                                                                                     
/home/ffortier/test.sh

Il mio file test.sh è simile al seguente:

#!/bin/bash
echo $(realpath "$1")

Se provo a eseguire quanto segue, viene visualizzato un errore

$ ./test.sh test.sh 
./test.sh: line 2: realpath: command not found

Come posso usare il comando realpath all'interno di un file bash?

Informazioni aggiuntive

$ type -a realpath
realpath is a function                                                                                                                                                                        
realpath ()                                                                                                                                                                                   
{                                                                                                                                                                                             
    f=$@;                                                                                                                                                                                     
    if [ -d "$f" ]; then                                                                                                                                                                      
        base="";                                                                                                                                                                              
        dir="$f";                                                                                                                                                                             
    else                                                                                                                                                                                      
        base="/$(basename "$f")";                                                                                                                                                             
        dir=$(dirname "$f");                                                                                                                                                                  
    fi;                                                                                                                                                                                       
    dir=$(cd "$dir" && /bin/pwd);                                                                                                                                                             
    echo "$dir$base"                                                                                                                                                                          
}           

Risposte:


9

Realpath è un comando reale o uno script? Vorrei verificare da dove proviene.

$ type -a realpath

Non ho familiarità con questo strumento, quindi probabilmente non fa parte della tua normale distribuzione, forse è installato in una posizione non standard che non è presente su Bash $PATHma si trova all'interno del tuo ambiente di accesso $PATH.

In ogni caso, il typecomando sopra ti mostrerà da dove proviene il comando, a quel punto puoi modificare il metodo che stai chiamando nel tuo script in questo modo:

echo $(/path/to/realpath test.sh)

O modifica il tuo script in $PATHmodo che includa anche questa posizione non standard.

Funzioni nella shell

Gran parte del tuo ambiente non viene chiamato quando invochi uno script di shell. Se ci pensate, questo ha molto senso, dal momento che in genere non volete che gli script abbiano tutto il bagaglio aggiuntivo che potrebbe avere un ambiente dell'utente.

Puoi determinare quale file di origine fornisce questa funzione e crearne una, oppure semplicemente indicare a Bash di incorporare il tuo ambiente di accesso.

#!/bin/bash -l
echo $(realpath "$1")

È una funzione, vedi modifica
Francis,

@Francis - sì, le funzioni non sono incluse quando invochi il tuo script. Dovrai procurarli se vuoi che arrivino. Scopri quale file fornisce la funzione e sorgente. Se vuoi solo tutto il tuo ambiente. quindi modificare la chiamata a bash, #!/bin/bash -l.
slm

Come posso trovare da dove proviene questa funzione?
Francesco,

1
@mikeserv - grazie, quando l'ho scritto stavo ancora usando Fedora 14 che non includeva realpath. Il mio sistema Fedora 19 ora include questo strumento. Si noti inoltre che l'OP utilizzava un kernel Debian con 2.6, quindi anche il suo sistema sarebbe mancato alla realpathsua età.
slm

1
@mikeserv - sì, sono stato sorpreso, questo è un Q vecchio stile ora, ma le informazioni su mi sono commandstate ancora utili. È un modo più portatile per fare ciò che stavo mostrando attraverso le shell POSIX.
slm

27

Esistono almeno due programmi chiamati realpath:

  • Un vecchio programma dal retro quando i coreutils GNU non includevano readlink -f. Ora è deprecato a favore readlink -f, quindi molte distribuzioni hanno smesso di trasportarlo.
  • Il realpathprogramma introdotto in GNU coreutils 8.15. Questo è troppo vecchio per essere in compressione Debian o anche sibilante; al momento in cui scrivo, Debian unstable non lo spedisce neanche . Questo programma è molto vicino readlink -f.

Per qualche motivo, hai una funzione shell che emula parzialmente il comportamento di realpath. Questa emulazione è parziale: se la chiami su un collegamento simbolico, non segue il collegamento simbolico.

Poiché questa è una funzione shell, presumibilmente caricata da o via .bashrc, è disponibile solo per il codice in esecuzione nella shell interattiva. Se vuoi che sia disponibile per altri programmi, supponendo che tu stia eseguendo Linux, crea uno script che emula realpath:

#!/bin/sh
readlink -f -- "$@"

(Questo non emula realpathle opzioni della riga di comando utilizzate raramente.)


2
Non trovo alcuna prova nel repository git di coreutils che il realpathprogramma è considerato deprecato da coreutils o che non è stato creato per impostazione predefinita. Quindi Debian deve rimuoverlo.
Kaz,

@Kaz Oh, beh, solo per complicare le cose, coreutils recentemente (8.15) ha introdotto un realpathbinario, che è vicino ma non esattamente identico a readlink -f. La scuderia Debian trasporta 8.13. Debian unstable ha scelto di mantenere il programma legacy .
Gilles 'SO- smetti di essere cattivo' il

Non era che di recente - era gennaio 2012. savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv

1
@mikeserv Troppo recente per la distribuzione nella domanda (compressione Debian). Anche troppo recente per l'attuale scuderia Debian.
Gilles 'SO- smetti di essere malvagio' il

È un po 'spaventoso. Quanti anni ha openssl?
Mikeserv,

8

Funziona solo nella shell, perché il file di script ha un ambito diverso e non ha accesso alle funzioni e agli alias locali definiti nei file rc . E il realpathcomando in realtà non esiste nel tuo sistema.

Quindi o installa realpathdal pacchetto, definisci la tua funzione (come parte dello script, controlla alcuni esempi ) o dai origine al file rc nello script dove è definito (ad es . ~/.bashrc.).


Ecco i passaggi per l'installazione realpathse non è presente:

  • Ubuntu: sudo apt-get install coreutils
  • OS X: brew install coreutils

Ubuntu e Debian

Su Debian o Ubuntu sembra che realpathdovrebbe essere installato di default. Ho controllato il recente Debian 8 (Jessie) e sembra averlo coreutilsinstallato di default.

Testato utilizzando nuove immagini VM:

$ vagrant init debian/jessie64 && vagrant up --provider virtualbox && vagrant ssh
$ vagrant init ubuntu/vivid64 && vagrant up --provider virtualbox && vagrant ssh

Quindi in VM:

$ type -a realpath
realpath is /usr/bin/realpath

Invece di realpath, puoi anche usare readlink -f file(o greadlink) fornito anche dal coreutilspacchetto.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.