Ada beberapa cara:
$0
adalah skrip yang saat ini sedang dijalankan sebagaimana disediakan oleh POSIX, relatif terhadap direktori kerja saat ini jika skrip berada pada atau di bawah CWD
- Selain itu,
cwd()
, getcwd()
dan abs_path()
disediakan olehCwd
modul dan memberitahu Anda di mana script sedang dijalankan dari
- Modul ini
FindBin
menyediakan $Bin
& $RealBin
variabel yang biasanya merupakan jalur ke skrip pelaksana; modul ini juga menyediakan $Script
& $RealScript
yang merupakan nama skrip
__FILE__
adalah file aktual yang ditangani interpreter Perl selama kompilasi, termasuk path lengkapnya.
Saya telah melihat tiga pertama ( $0
, Cwd
modul dan FindBin
modul) gagal secara mod_perl
spektakuler, menghasilkan output yang tidak berharga seperti '.'
atau string kosong. Dalam lingkungan seperti itu, saya menggunakan __FILE__
dan mendapatkan jalur dari itu menggunakan File::Basename
modul:
use File::Basename;
my $dirname = dirname(__FILE__);
__FILE__
) tidak berfungsi seperti yang diharapkan? Saya berakhir dengan jalur relatif dari tempat skrip dieksekusi, sementara jawaban yang diterima memberi saya jalur absolut penuh.dirname(__FILE__)
tidak mengikuti symlinks, jadi jika Anda menautkan file yang dapat dieksekusi dan di mana berharap menemukan lokasi beberapa file lain di lokasi instal Anda perlu memeriksaif( -l __FILE__)
dan kemudiandirname(readlink(__FILE__))
.perl -e 'use Module::CoreList; print Module::CoreList->first_release("File::Basename");'; echo
. UntukFile::Basename
itu adalah Perl 5.0.0, yang dirilis pada akhir 90-an — saya pikir ini aman untuk digunakan sekarang.$ 0 biasanya nama program Anda, jadi bagaimana dengan ini?
Menurut saya ini seharusnya berfungsi karena abs_path tahu jika Anda menggunakan jalur relatif atau absolut.
Pembaruan Untuk siapa pun yang membaca ini tahun kemudian, Anda harus membaca jawaban Drew . Ini jauh lebih baik daripada milikku.
sumber
realpath
, yang merupakan sinonim denganabs_path
, jika Anda lebih suka nama tanpa garis bawahperl -e 'use Cwd "abs_path";print abs_path($0);'
cetakan/tmp/-e
-e
), saya percaya perl membuat file temp untuk menyimpan skrip inline Anda. Sepertinya lokasi, dalam kasus Anda, adalah/tmp
. Apa yang Anda harapkan dari hasilnya?http://perldoc.perl.org/File/Spec/Unix.html
sumber
Saya pikir modul yang Anda cari adalah FindBin:
sumber
Anda bisa menggunakan FindBin , CWD , File :: basename , atau kombinasi dari mereka. Semuanya ada di distribusi dasar Perl IIRC.
Saya menggunakan Cwd di masa lalu:
Cwd:
sumber
Mendapatkan jalur absolut
$0
atau__FILE__
apa yang Anda inginkan. Satu-satunya masalah adalah jika seseorang melakukanchdir()
dan$0
itu relatif - maka Anda perlu mendapatkan jalur absolut dalamBEGIN{}
untuk mencegah kejutan.FindBin
mencoba untuk pergi yang lebih baik dan merendahkan diri di dalam$PATH
untuk sesuatu yang cocokbasename($0)
, tetapi ada kalanya hal-hal yang jauh terlalu mengejutkan (khususnya: ketika file "tepat di depan Anda" di cwd.)File::Fu
memilikiFile::Fu->program_name
danFile::Fu->program_dir
untuk ini.sumber
chdir()
pada waktu kompilasi?Beberapa latar belakang pendek:
Sayangnya Unix API tidak menyediakan program yang berjalan dengan jalur lengkap ke yang dapat dieksekusi. Bahkan, program yang menjalankan program Anda dapat memberikan apa pun yang diinginkan di bidang yang biasanya memberi tahu program Anda tentang apa itu. Ada, seperti semua jawaban tunjukkan, berbagai heuristik untuk menemukan calon yang mungkin. Tapi tidak ada kekurangan mencari seluruh sistem file akan selalu bekerja, dan bahkan itu akan gagal jika executable dipindahkan atau dihapus.
Tetapi Anda tidak ingin Perl dapat dieksekusi, yang sebenarnya sedang berjalan, tetapi skrip yang dieksekusi. Dan Perl perlu tahu di mana skrip itu menemukannya. Ini menyimpan ini
__FILE__
, sementara$0
dari API Unix. Ini masih bisa menjadi jalur relatif, jadi terima saran Mark dan dikanonkanFile::Spec->rel2abs( __FILE__ );
sumber
__FILE__
masih memberi saya jalan relatif. yaitu '.'.Sudahkah Anda mencoba:
atau
Itu benar-benar tergantung pada bagaimana itu dipanggil dan apakah itu CGI atau dijalankan dari shell normal, dll.
sumber
Untuk mendapatkan jalur ke direktori yang berisi skrip saya, saya telah menggunakan kombinasi jawaban yang sudah diberikan.
sumber
perlfaq8 menjawab pertanyaan yang sangat mirip dengan menggunakan
rel2abs()
fungsi aktif$0
. Fungsi itu dapat ditemukan di File :: Spec.sumber
Tidak perlu menggunakan modul eksternal, hanya dengan satu baris Anda dapat memiliki nama file dan jalur relatif. Jika Anda menggunakan modul dan perlu menerapkan jalur relatif ke direktori skrip, jalur relatif sudah cukup.
sumber
:DD
sumber
Apakah Anda mencari ini ?:
Outputnya akan terlihat seperti ini:
Ini bekerja pada Windows dan Unix.
sumber
sumber
Masalahnya
__FILE__
adalah bahwa ia akan mencetak jalur modul inti ".pm" belum tentu jalur skrip ".cgi" atau ".pl" yang sedang berjalan. Saya kira itu tergantung pada apa tujuan Anda.Menurut saya itu
Cwd
hanya perlu diperbarui untuk mod_perl. Ini saran saya:Silakan tambahkan saran.
sumber
Tanpa modul eksternal, valid untuk shell, berfungsi dengan baik bahkan dengan '../':
uji:
sumber
Masalah dengan hanya menggunakan
dirname(__FILE__)
adalah tidak mengikuti symlink. Saya harus menggunakan ini untuk skrip saya untuk mengikuti symlink ke lokasi file yang sebenarnya.sumber
Semua solusi bebas pustaka sebenarnya tidak berfungsi lebih dari beberapa cara untuk menulis lintasan (pikirkan ../ atau /bla/x/../bin/./x/../ dll. Solusi saya terlihat seperti di bawah ini. Saya punya satu kekhasan: Saya tidak punya ide sedikit pun mengapa saya harus menjalankan penggantian dua kali. Jika tidak, saya mendapatkan palsu "./" atau "../". Selain itu, itu sepertinya cukup kuat untukku.
sumber
Tidak ada jawaban "atas" yang tepat untuk saya. Masalah dengan menggunakan FindBin '$ Bin' atau Cwd adalah mereka mengembalikan path absolut dengan semua tautan simbolik diselesaikan. Dalam kasus saya, saya membutuhkan jalur yang tepat dengan tautan simbolik yang ada - sama seperti mengembalikan perintah Unix "pwd" dan bukan "pwd -P". Fungsi berikut menyediakan solusinya:
sumber
Di Windows, menggunakan
dirname
danabs_path
bersama - sama bekerja paling baik untuk saya.inilah sebabnya:
sumber
Ada apa dengan ini
$^X
?Akan memberi Anda path lengkap ke biner Perl yang digunakan.
Evert
sumber
Pada * nix, Anda mungkin memiliki perintah "whereis", yang mencari $ PATH Anda mencari biner dengan nama yang diberikan. Jika $ 0 tidak mengandung nama path lengkap, menjalankan $ scriptname di mana dan menyimpan hasilnya ke dalam variabel akan memberi tahu Anda di mana skrip berada.
sumber