Di Linux, readlink
utilitas menerima opsi -f
yang mengikuti tautan tambahan. Ini sepertinya tidak berfungsi pada Mac dan mungkin sistem berbasis BSD. Apa yang akan menjadi setara?
Berikut ini beberapa informasi debug:
$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
readlink
dapat berupa builtin atau perintah eksternal.touch myfile ; ln -s myfile otherfile ; perl -MCwd=abs_path -le 'print abs_path readlink(shift);' otherfile
... dalam kasus saya, saya melihat: / Users / cito / myfile`. Menambahkannya ke respons saya di bawah ini. Bersulang.Jawaban:
readlink -f
melakukan dua hal:Jika Anda mau, Anda bisa membuat skrip shell yang menggunakan perilaku readlink vanilla untuk mencapai hal yang sama. Ini sebuah contoh. Jelas Anda bisa memasukkan ini ke dalam skrip Anda sendiri tempat Anda ingin menelepon
readlink -f
Perhatikan bahwa ini tidak termasuk penanganan kesalahan. Yang paling penting, ini tidak mendeteksi siklus symlink. Cara sederhana untuk melakukan ini adalah dengan menghitung berapa kali Anda berputar-putar dan gagal jika Anda menekan angka yang sangat besar, seperti 1.000.
Diedit untuk digunakan
pwd -P
sebagai gantinya$PWD
.Perhatikan bahwa skrip ini mengharapkan dipanggil seperti
./script_name filename
, tidak-f
, ubah$1
menjadi$2
jika Anda ingin dapat menggunakan dengan-f filename
tautan baca GNU seperti.sumber
foo -> /var/cux
, makafoo/bar
tidak akan diselesaikan, karenabar
bukan tautan, meskipun demikianfoo
.cd "$(dirname "$TARGET_FILE")"
danTARGET_FILE=$(readlink "$TARGET_FILE")
danTARGET_FILE=$(basename "$TARGET_FILE")
di tempat yang sesuai dalam kode di atas.MacPorts dan Homebrew menyediakan coreutils paket berisi
greadlink
(GNU readlink). Kredit ke posting Michael Kallweitt di mackb.com.sumber
.bashrc
:export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
pwd -P
danreadlink
pada OS X, tanpa menginstal apa punPATH
. Apakah di atas dimulai denganbrew install <package> --default-names
. Sering kali pertanyaan di situs ini sedikit dijawab, atau lebih tepatnya, di luar persyaratan teknis penanya, tetapi dalam situasi yang sama, dan masih sangat membantu. topbug.net/blog/2013/04/14/…Anda mungkin tertarik
realpath(3)
, atau Pythonos.path.realpath
. Keduanya tidak persis sama; panggilan pustaka C mengharuskan komponen jalur perantara ada, sedangkan versi Python tidak.Saya tahu Anda mengatakan Anda lebih suka sesuatu yang lebih ringan daripada bahasa scripting lain, tetapi kalau-kalau kompilasi biner tidak dapat disangkal, Anda dapat menggunakan Python dan ctypes (tersedia di Mac OS X 10.5) untuk membungkus panggilan perpustakaan:
Ironisnya, versi C dari skrip ini seharusnya lebih pendek. :)
sumber
realpath
memang itulah yang saya inginkan. Tapi sepertinya agak canggung bahwa saya harus mengkompilasi biner untuk mendapatkan fungsi ini dari skrip shell.readlink
dirinya sendiri, bukan?)python -c "import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))" "${1}"
bekerja dengan jalur seperti'~/.symlink'
perl -MCwd=abs_path -le 'print abs_path readlink(shift);'
jawaban saya :-)Saya benci untuk melanjutkan dengan implementasi lain, tetapi saya membutuhkan a) implementasi portabel, shell murni , dan b) cakupan unit-test , karena jumlah kasus tepi untuk sesuatu seperti ini adalah non-sepele .
Lihat proyek saya di Github untuk tes dan kode lengkap. Berikut ini adalah sinopsis implementasi:
Seperti yang ditunjukkan Keith Smith dengan cerdas,
readlink -f
lakukan dua hal: 1) menyelesaikan symlink secara rekursif, dan 2) mengkanoniskan hasilnya, dengan demikian:Pertama, implementasi resollink symlink:
Perhatikan bahwa ini adalah versi implementasi penuh yang sedikit disederhanakan . Implementasi penuh menambahkan cek kecil untuk siklus symlink , serta memijat output sedikit.
Akhirnya, fungsi untuk mengkanonik jalur:
Itu dia, kurang lebih. Cukup sederhana untuk disisipkan ke skrip Anda, tetapi cukup rumit sehingga Anda akan gila untuk mengandalkan kode apa pun yang tidak memiliki tes unit untuk kasus penggunaan Anda.
sumber
local
kata kunci non-POSIXreadlink -f
, atau darirealpath
. Dengan asumsi Mac dengan formula coreutils terinstal (demikian dengangreadlink
tersedia), coba ini denganln -s /tmp/linkeddir ~/Documents
;greadlink -f /tmp/linkeddir/..
mencetak direktori home Anda (itu menyelesaikan/tmp/linkeddir
tautan sebelum menerapkan..
dir induk), tetapi kode Anda menghasilkan/private/tmp/
as/tmp/linkeddir/..
bukan symlink, tetapi-d /tmp/linkeddir/..
benar dancd /tmp/linkeddir/..
membawa Anda ke/tmp
, yang jalur kanoniknya adalah/private/tmp
. Kode Anda melakukan apa yang harusrealpath -L
dilakukan.Satu-liner sederhana di perl yang pasti akan bekerja hampir di mana saja tanpa ketergantungan eksternal:
Will dereference symlinks.
Penggunaan dalam skrip bisa seperti ini:
sumber
-l
, tambahkan , sepertiperl -MCwd -le 'print Cwd::abs_path shift' ~/non-absolute/file
greadlink adalah readlink gnu yang mengimplementasikan -f. Anda dapat menggunakan macports atau lainnya juga, saya lebih suka homebrew.
sumber
Saya membuat sebuah skrip bernama realpath pribadi yang terlihat seperti:
sumber
sys.argv[1]
jika Anda ingin skrip untuk mencetak jalur sebenarnya dari argumen pertama.sys.argv[0]
hanya mencetak jalur sebenarnya dari skrip pyton itu sendiri, yang tidak terlalu berguna.~/.profile
:alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[1])'"
readlink -f
, berikut ini adalah versi modifikasi alias @jwhitlock untuk mendukung kemungkinan-f
flag:alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[2] if sys.argv[1] == \"-f\" else sys.argv[1])'"
Bagaimana dengan ini?
sumber
../../../
->/
/usr/bin/
misalnya sepertialternatives
sistem suka miliki.Ini adalah fungsi shell portabel yang bisa digunakan di APAPUN shell sebanding Bourne. Ini akan menyelesaikan tanda baca jalur relatif ".. atau." dan tautan simbolik dereferensi.
Jika karena alasan tertentu Anda tidak memiliki perintah realpath (1), atau readlink (1) ini dapat alias.
Nikmati:
juga, kalau-kalau ada orang yang tertarik di sini adalah bagaimana menerapkan nama samaran dan dirname dalam kode shell 100% murni:
Anda dapat menemukan versi terbaru dari kode shell ini di situs google saya: http://sites.google.com/site/jdisnard/realpath
EDIT: Kode ini dilisensikan berdasarkan ketentuan lisensi 2-klausa (gaya freeBSD). Salinan lisensi dapat ditemukan dengan mengikuti hyperlink di atas ke situs saya.
sumber
FreeBSD dan OSX memiliki versi
stat
turunan dari NetBSD.Anda dapat menyesuaikan output dengan sakelar format (lihat halaman manual pada tautan di atas).
Beberapa versi OS X
stat
mungkin tidak memiliki-f%R
opsi untuk format. Dalam hal ini-stat -f%Y
mungkin sudah cukup. The-f%Y
pilihan akan menunjukkan target symlink, sedangkan-f%R
menunjukkan nama path absolut sesuai dengan file.EDIT:
Jika Anda dapat menggunakan Perl (Darwin / OS X dilengkapi dengan versi terbaru dari
perl
) maka:akan bekerja.
sumber
R
pilihan untuk-f%
hilang. Mungkinstat -f%Y
memberikan output yang diinginkan. Saya akan menyesuaikan jawabannya. Perhatikan bahwastat
alat ini muncul di FreeBSD di versi 4.10 dan NetBSD di versi 1.6.Cara termudah untuk menyelesaikan masalah ini dan mengaktifkan fungsionalitas readlink pada Mac dengan Homebrew yang diinstal atau FreeBSD adalah dengan menginstal paket 'coreutils'. Mungkin juga diperlukan pada distribusi Linux tertentu dan OS POSIX lainnya.
Sebagai contoh, di FreeBSD 11, saya menginstal dengan memohon:
# pkg install coreutils
Pada MacOS dengan Homebrew, perintahnya adalah:
$ brew install coreutils
Tidak begitu yakin mengapa jawaban lain begitu rumit, hanya itu yang ada di sana. File-file tidak di tempat yang berbeda, mereka hanya belum diinstal.
sumber
brew install coreutils --with-default-names
untuk lebih spesifik. Atau Anda akan berakhir dengan "greadlink" sebagai gantinya ...pwd -P
cukup sederhana tetapi menghilang di antara banyak jawaban lain, termasuk yang diulang, maka downvote.Mulai Perbarui
Ini adalah masalah yang sering terjadi sehingga kami mengumpulkan perpustakaan Bash 4 untuk penggunaan gratis (Lisensi MIT) yang disebut realpath-lib . Ini dirancang untuk mengemulasi readlink -f secara default dan menyertakan dua test suite untuk memverifikasi (1) bahwa ia berfungsi untuk sistem unix yang diberikan dan (2) terhadap readlink -f jika diinstal (tetapi ini tidak diperlukan). Selain itu, ini dapat digunakan untuk menyelidiki, mengidentifikasi, dan melepaskan symlink yang dalam dan rusak, sehingga dapat menjadi alat yang berguna untuk mendiagnosis masalah fisik dan simbolik direktori dan file yang bersarang. Hal ini dapat ditemukan di github.com atau bitbucket.org .
Akhiri Pembaruan
Solusi lain yang sangat ringkas dan efisien yang tidak bergantung pada apa pun kecuali Bash adalah:
Ini juga termasuk pengaturan lingkungan
no_symlinks
yang menyediakan kemampuan untuk menyelesaikan symlink ke sistem fisik. Selamano_symlinks
diatur ke sesuatu, yaituno_symlinks='on'
symlink akan diselesaikan ke sistem fisik. Kalau tidak mereka akan diterapkan (pengaturan default).Ini harus bekerja pada sistem apa pun yang menyediakan Bash, dan akan mengembalikan kode keluar yang kompatibel dengan Bash untuk tujuan pengujian.
sumber
Sudah ada banyak jawaban, tetapi tidak ada yang berhasil untuk saya ... Jadi ini yang saya gunakan sekarang.
sumber
$target
path, hanya berfungsi jika itu file.Cara malas yang bekerja untuk saya,
sumber
Lebih baik terlambat daripada tidak, kurasa. Saya termotivasi untuk mengembangkan ini secara khusus karena skrip Fedora saya tidak berfungsi pada Mac. Masalahnya adalah dependensi dan Bash. Mac tidak memilikinya, atau jika ya, sering ada di tempat lain (jalur lain). Manipulasi jalur ketergantungan dalam skrip Bash lintas-platform adalah sakit kepala paling-paling dan risiko keamanan paling buruk - jadi sebaiknya hindari penggunaannya, jika mungkin.
Fungsi get_realpath () di bawah ini sederhana, Bash-centric, dan tidak ada ketergantungan yang diperlukan. Saya hanya menggunakan echo dan cd bawaan Bash . Ini juga cukup aman, karena semuanya diuji pada setiap tahap dan mengembalikan kondisi kesalahan.
Jika Anda tidak ingin mengikuti symlink, maka letakkan set -P di bagian depan skrip, tetapi jika tidak cd akan menyelesaikan symlink secara default. Ini telah diuji dengan argumen file yang {absolute | kerabat | symlink | local} dan mengembalikan path absolut ke file. Sejauh ini kami tidak punya masalah dengan itu.
Anda dapat menggabungkan ini dengan fungsi lain get_dirname, get_filename, get_stemname dan validate_path. Ini dapat ditemukan di repositori GitHub kami sebagai realpath-lib (pengungkapan penuh - ini adalah produk kami tetapi kami menawarkannya secara gratis kepada komunitas tanpa batasan). Itu juga bisa berfungsi sebagai alat instruksional - itu didokumentasikan dengan baik.
Kami telah mencoba yang terbaik untuk menerapkan praktik yang disebut 'Bash modern', tetapi Bash adalah subjek besar dan saya yakin akan selalu ada ruang untuk perbaikan. Ini membutuhkan Bash 4+ tetapi bisa dibuat untuk bekerja dengan versi yang lebih lama jika masih ada.
sumber
Karena pekerjaan saya digunakan oleh orang-orang dengan Linux non-BSD dan juga macOS, saya telah memilih untuk menggunakan alias ini dalam skrip build kami (
sed
termasuk karena memiliki masalah yang sama):Pemeriksaan opsional yang dapat Anda tambahkan untuk menginstal dependensi homebrew + coreutils secara otomatis :
Saya kira benar-benar "global" perlu memeriksa orang lain ... tapi itu mungkin mendekati tanda 80/20.
sumber
Penjelasan
coreutils adalah
brew
paket yang menginstal utilitas inti GNU / Linux yang sesuai dengan implementasi Mac OSX sehingga Anda dapat menggunakannyaAnda mungkin menemukan program atau utilitas pada sistem mac osx Anda yang tampaknya mirip dengan Linux coreutils ("Core Utilities") namun mereka berbeda dalam beberapa hal (seperti memiliki flag yang berbeda).
Ini karena implementasi Mac OSX dari alat-alat ini berbeda. Untuk mendapatkan perilaku mirip GNU / Linux asli, Anda dapat menginstal
coreutils
paket melaluibrew
sistem manajemen paket.Ini akan menginstal utilitas inti yang sesuai, diawali oleh
g
. Misalnya untukreadlink
, Anda akan menemukangreadlink
program yang sesuai .Untuk membuat
readlink
kinerja seperti implementasi GNUreadlink
(greadlink
), Anda dapat membuat alias sederhana setelah Anda menginstal coreutils.Penerapan
Ikuti instruksi di https://brew.sh/
brew install coreutils
Anda dapat menempatkan alias Anda di ~ / .bashrc, ~ / .bash_profile, atau di mana pun Anda terbiasa menyimpan alias bash Anda. Saya pribadi menyimpan milik saya di ~ / .bashrc
alias readlink=greadlink
Anda dapat membuat alias serupa untuk coreutils lainnya seperti gmv, gdu, gdf, dan sebagainya. Tetapi berhati-hatilah bahwa perilaku GNU pada mesin mac mungkin membingungkan bagi orang lain yang terbiasa bekerja dengan coreutils asli, atau mungkin berperilaku dengan cara yang tidak terduga pada sistem mac Anda.
sumber
Saya menulis utilitas realpath untuk OS X yang dapat memberikan hasil yang sama seperti
readlink -f
.Berikut ini sebuah contoh:
Jika Anda menggunakan MacPorts, Anda dapat menginstalnya dengan perintah berikut:
sudo port selfupdate && sudo port install realpath
.sumber
Benar-benar platform-indpendent juga akan menjadi R-onliner ini
Untuk benar-benar meniru
readlink -f <path>
, $ 2 dan bukan $ 1 harus digunakan.sumber
readlink -f
Implementasi yang sesuai dengan POSIX untuk skrip shell POSIXhttps://github.com/ko1nksm/readlinkf
Ini adalah POSIX compliant (tidak ada bashism). Tidak menggunakan juga
readlink
tidakrealpath
. Saya telah memverifikasi bahwa persis sama dengan membandingkan dengan GNUreadlink -f
(lihat hasil tes ). Ini memiliki penanganan kesalahan dan kinerja yang baik. Anda dapat dengan aman mengganti darireadlink -f
. Lisensi tersebut adalah CC0, sehingga Anda dapat menggunakannya untuk proyek apa pun.Silakan merujuk ke kode terbaru. Mungkin beberapa diperbaiki.
sumber
Perl memiliki fungsi readlink (mis. Bagaimana cara menyalin tautan simbolik di Perl? ). Ini berfungsi di sebagian besar platform, termasuk OS X:
Sebagai contoh:
sumber
readlink
tanpa-f
opsi - tidak ada rekursi, tidak ada jalur absolut -, jadi sebaiknya Anda gunakanreadlink
secara langsung.Jawaban dari @Keith Smith memberikan loop tak terbatas.
Inilah jawaban saya, yang saya gunakan hanya pada SunOS (SunOS kehilangan begitu banyak perintah POSIX dan GNU).
Ini adalah file skrip yang harus Anda masukkan ke dalam salah satu dari direktori $ PATH Anda:
sumber
Inilah yang saya gunakan:
stat -f %N $your_path
sumber
Path ke readlink berbeda antara sistem saya dan Anda. Silakan coba tentukan path lengkap:
sumber
readlink
gnu yang kompatibel. Itu menyenangkan untuk diketahui, tetapi itu tidak menyelesaikan masalah saya, karena saya perlu skrip saya untuk dijalankan pada mesin orang lain, dan saya tidak bisa meminta mereka untuk menginstal fink untuk itu.