perintah realpath tidak ditemukan

24

Saya memiliki debian squeeze amd64. Shell saya sekarang adalah bash. Jika saya menulis yang berikut di terminal saya, itu berfungsi:

$ 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

File test.sh saya terlihat seperti ini:

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

Jika saya mencoba menjalankan yang berikut ini, saya mendapatkan kesalahan

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

Bagaimana saya bisa menggunakan perintah realpath dalam file bash?

informasi tambahan

$ 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"                                                                                                                                                                          
}           
Francis
sumber

Jawaban:

9

Apakah realpath adalah perintah atau skrip aktual? Saya akan memeriksa untuk melihat dari mana asalnya.

$ type -a realpath

Saya tidak terbiasa dengan alat ini, dan karena itu kemungkinan bukan bagian dari distribusi normal Anda, mungkin itu dipasang di lokasi non-standar yang tidak ada pada Bash $PATHtetapi berada dalam lingkungan login Anda $PATH.

Bagaimanapun, typeperintah di atas akan menunjukkan kepada Anda dari mana perintah itu berasal, pada titik mana Anda dapat mengubah metode yang Anda panggil dalam skrip Anda seperti:

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

Atau ubah skrip Anda $PATHsehingga termasuk lokasi yang tidak standar ini.

Fungsinya di shell

Sebagian besar lingkungan Anda tidak dipanggil saat Anda menjalankan skrip shell. Jika Anda memikirkan hal ini, ini sangat masuk akal, karena Anda biasanya tidak ingin skrip memiliki semua bagasi tambahan yang mungkin dimiliki oleh lingkungan pengguna.

Anda dapat menentukan file sumber mana yang menyediakan fungsi ini dan sumbernya, atau hanya menginstruksikan Bash untuk memasukkan lingkungan login Anda.

#!/bin/bash -l
echo $(realpath "$1")
slm
sumber
Ini sebuah fungsi, lihat sunting
Francis
@ Francis - ya fungsi tidak termasuk ketika Anda menjalankan skrip Anda. Anda harus sumber mereka jika Anda ingin mereka datang. Cari tahu file mana yang menyediakan fungsi dan sumbernya. Jika Anda hanya ingin seluruh env Anda. kemudian ubah panggilan Anda menjadi bash #!/bin/bash -l,.
slm
Bagaimana saya bisa menemukan dari mana fungsi ini berasal?
Francis
1
@ mikeserv - terima kasih, ketika saya menulis ini saya masih menggunakan Fedora 14 yang tidak termasuk realpath. Sistem Fedora 19 saya sekarang termasuk alat ini. Juga perhatikan OP menggunakan kernel Debian w / 2.6, jadi sistemnya juga akan hilang realpathmengingat usianya.
slm
1
@ mikeserv - ya saya terkejut, ini adalah Q lama-ish sekarang, tapi info tentang commanditu masih berguna bagi saya. Ini cara yang lebih portabel untuk melakukan apa yang saya tunjukkan di seluruh cangkang POSIX.
slm
27

Setidaknya ada dua program yang disebut realpath:

  • Program lama dari belakang ketika GNU coreutils tidak termasuk readlink -f. Sekarang sudah tidak digunakan lagi readlink -f, sehingga banyak distribusi telah berhenti membawanya.
  • The realpathProgram diperkenalkan pada GNU coreutils 8.15. Ini terlalu tua untuk diperas Debian atau bahkan mengi; pada saat penulisan, Debian tidak stabil juga tidak mengirimkannya . Program ini sangat dekat readlink -f.

Untuk beberapa alasan, Anda memiliki fungsi shell yang sebagian meniru perilaku realpath. Persaingan ini sebagian: jika Anda menyebutnya pada tautan simbolik, itu tidak mengikuti tautan simbolik.

Karena ini adalah fungsi shell, mungkin dimuat dari atau melalui .bashrc, itu hanya tersedia untuk kode yang berjalan di shell interaktif Anda. Jika Anda ingin itu tersedia untuk program lain, dengan asumsi Anda menjalankan Linux, buat skrip yang meniru realpath:

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

(Ini tidak meniru realpathopsi baris perintah yang jarang digunakan.)

Gilles 'SANGAT berhenti menjadi jahat'
sumber
2
Saya tidak dapat menemukan bukti di coreutils git repo bahwa realpathprogram tersebut dianggap usang oleh coreutils, atau bahwa itu tidak dibangun secara default. Jadi Debian harus menghapusnya.
Kaz
@ Ka Oh, well, hanya untuk memperumit masalah, coreutils baru-baru ini (8,15) memperkenalkan realpathbiner, yang dekat tapi tidak persis sama dengan readlink -f. Stabil Debian membawa 8.13. Debian tidak stabil memilih untuk mempertahankan program warisan .
Gilles 'SANGAT berhenti menjadi jahat'
Itu tidak bahwa baru-baru ini - itu 2012. Jan savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv
1
@ mikeserv Jauh terlalu baru untuk distribusi dalam pertanyaan (Debian squeeze). Bahkan terlalu baru untuk stabil Debian saat ini.
Gilles 'SANGAT berhenti menjadi jahat'
Itu agak menakutkan. Berapa umur mereka openssl?
mikeserv
8

Ini hanya berfungsi di shell, karena file skrip memiliki cakupan yang berbeda dan tidak memiliki akses ke fungsi lokal Anda atau alias yang ditentukan dalam file rc Anda . Dan realpathperintah sebenarnya tidak ada di sistem Anda.

Jadi instal realpathdari paket, tentukan fungsi Anda sendiri (sebagai bagian dari skrip, periksa beberapa contoh ) atau sumber file rc di skrip Anda di tempat yang ditentukan (misalnya . ~/.bashrc).


Berikut langkah-langkah untuk menginstal realpathjika tidak ada:

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

Ubuntu & Debian

Pada Debian atau Ubuntu tampaknya realpathharus diinstal secara default. Saya telah memeriksa di Debian 8 (Jessie) baru-baru ini dan tampaknya telah coreutilsdiinstal secara default.

Diuji menggunakan gambar VM segar:

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

Kemudian di VM:

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

Alih-alih realpath, Anda juga dapat menggunakan readlink -f file(atau greadlink) yang disediakan oleh coreutilspaket juga.

kenorb
sumber
5
$ sudo apt-get install realpath
pengguna175315
sumber