Saat menulis skrip bash, bagaimana cara mendapatkan path absolut dari lokasi file saat ini?

15

Misalkan saya memiliki file bash yang disebut myBash.bash. Itu berada di:

/myDirect/myFolder/myBash.bash

Sekarang saya ingin menggunakan string /myDirect/myFolder(lokasi myBash.bash) di dalam skrip. Apakah ada perintah yang bisa saya gunakan untuk menemukan lokasi ini?

Sunting: Idenya adalah saya ingin mengatur folder zip dengan kode yang dapat dimulai dengan skrip bash di dalam file zip itu. Saya tahu path file relatif dari kode di dalam file zip itu, tetapi bukan path absolut, dan saya membutuhkannya. Salah satu caranya adalah dengan hard-code di path, atau membutuhkan path file yang akan diberikan sebagai variabel. Namun saya akan merasa lebih mudah jika mungkin untuk file-bash untuk mencari tahu di mana itu sendiri dan kemudian membuat jalur yang relevan ke file lain dari pengetahuan tentang struktur file zip.

dimpol
sumber
3
Ini mungkin lebih cocok untuk stackoverflow. Periksa pertanyaan-pertanyaan ini: stackoverflow.com/questions/4774054/… stackoverflow.com/questions/59895/… .
Sethos II
1
gunakan bagaimana.? mohon klarifikasi
Sergiy Kolodyazhnyy
1
@SethosII pertanyaan ini benar-benar tentang topik di sini
Zanna
1
Saya menambahkan lebih banyak konteks untuk pertanyaan itu. Saya pikir mungkin ada perintah yang mudah / jelas untuk mendapatkan path file dari file yang sedang dieksekusi, tetapi tampaknya jawabannya setidaknya tidak jelas.
dimpol
3
@Zanna Saya tidak mengatakan itu offtopic, saya pikir itu lebih tepat dan seperti yang ditunjukkan dengan tautan yang sudah ditanyakan dan dijawab di sana beberapa kali.
Sethos II

Jawaban:

23

Anda bisa mendapatkan path lengkap seperti:

realpath "$0"

Dan seperti yang ditunjukkan oleh Serg Anda dapat menggunakan dirnameuntuk menghapus nama file seperti ini

dirname "$(realpath $0)"

atau bahkan lebih baik untuk mencegah kutipan canggung dan pemisahan kata dengan nama file yang sulit:

temp=$( realpath "$0"  ) && dirname "$temp"

Jauh lebih baik daripada ide saya sebelumnya yang menguraikannya (saya tahu akan ada cara yang lebih baik!)

realpath "$0" | sed 's|\(.*\)/.*|\1|'

Catatan

  • realpath mengembalikan jalur sebenarnya dari suatu file
  • $0 apakah file ini (skrip)
  • s|old|new|ganti olddengannew
  • \(.*\)/simpan semua karakter sebelum /untuk nanti
  • \1 bagian yang disimpan
Zanna
sumber
2
+1 untuk penggunaan $0dan sedsihir. Tapi sedsihir itu benar-benar tidak perlu ketika alat seperti dirnameada
Sergiy Kolodyazhnyy
2
Anda sudah memiliki jawabannya, gunakan realpath: realpath "$( dirname $0 )"Saya pribadi akan menggunakan readlinktetapi itu saya:readlink -e $(dirname $0)
Sergiy Kolodyazhnyy
@Serg: Tidak dirname "$(realpath "$0")"akan lebih baik? Biasanya orang ingin mengetahui direktori induk dari file yang direferensikan alih-alih direktori induk dari tautan simbolik yang merujuk ke file tersebut.
David Foerster
4
@Serg "$(dirname "$(realpath "$0")")"adalah cara yang paling mudah. Kutipan di dalam $()pekerjaan seperti biasa.
DepressedDaniel
@DepressedDaniel Melakukan sedikit riset online, Anda benar: $()menjadi subkulit akan memungkinkan memiliki kutipan di luar. Saya tidak akan mengatakan itu sesederhana itu, kecuali orang menyadari $()semuanya subkulit
Sergiy Kolodyazhnyy
5

jika skrip berada di jalur Anda, Anda dapat menggunakan sesuatu seperti

$ myloc=$(dirname "$(which foo.sh)")
$ echo "$myloc"
/path/to/foo.sh

EDIT: setelah membaca komentar dari Serg, ini mungkin solusi umum yang berfungsi baik skrip ada di jalur Anda atau tidak.

myloc==$(dirname "$(realpath $0)")
dirname "$myloc"
Antonello Piemonte
sumber
whichlebih cocok ketika skrip berada di salah satu direktori yang merupakan bagian dari PATHvariabel. Gunakan $0dari dalam skrip, seperti yang ditampilkan Zanna. Tetapi jawaban Anda tepat karena Anda menggunakan dirnamealih-alih mengacaukan sed, maka +1 untuk itu
Sergiy Kolodyazhnyy
5

Jawaban yang diterima tampaknya sempurna. Berikut cara lain untuk melakukannya:

cd "$(dirname "$0")"
/bin/pwd

/bin/pwdmencetak path sebenarnya dari direktori, sebagai lawan dari pwdperintah builtin.

serv-inc
sumber
0
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0}";;
  *) scriptdir="$wdir/${0#./}";;
esac
scriptdir="${scriptdir%/*}"
echo "$scriptdir"

Ini diambil sebagai referensi dari kenorb dan andro
Tanpa dirname, readlink, realpath, BASH_SOURCE
Semua adalah builtin

Hemanth Jabalpuri
sumber