kutipan di dalamnya penting atau Anda akan kehilangan semua data Anda
catamphetamine
11
dan varian yang saya gunakan untuk mendapatkan induk dari direktori kerja saat ini: parentdir=$(dirname `pwd`)
TheGrimmScientist
3
Catatan, metode ini tidak aman untuk nama "jelek". Nama seperti "-rm -rf" akan mematahkan perilaku yang diinginkan. Mungkin "." akan juga. Saya tidak tahu apakah itu cara terbaik, tetapi saya telah membuat pertanyaan "fokus-benar" yang terpisah di sini: stackoverflow.com/questions/40700119/…
VasiliNovikov
4
@Christopher Shroba Ya, saya menghilangkan tanda kutip dan kemudian HDD saya sebagian terhapus. Saya tidak ingat persis apa yang terjadi: mungkin direktori whitespaced yang tidak dikutip membuatnya menghapus dir induk daripada yang target - skrip saya baru saja menghapus folder / home / xxx /.
catamphetamine
3
oh oke, jadi tidak ada apa-apa tentang perintah yang akan menyebabkan data hilang kecuali Anda sudah mengeluarkan perintah hapus, kan? Itu hanya masalah jalur yang Anda coba hapus untuk mendapatkan pemisahan pada karakter ruang dan menghapus lebih dari yang diharapkan?
Christopher Shroba
18
... tapi apa yang "terlihat di sini " rusak. Inilah solusinya:
Cukup gunakan echo $(cd ../ && pwd)saat bekerja di direktori yang direktori induknya ingin Anda ketahui. Rantai ini juga memiliki manfaat tambahan karena tidak memiliki garis miring.
Menggunakan evalTIDAK bagus jika ada kemungkinan parsing input pengguna yang dapat menempatkan Anda di tempat yang tidak Anda harapkan atau menjalankan hal-hal buruk terhadap sistem Anda. Bisakah Anda menggunakan pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/nullbukan eval?
dragon788
2
Anda tidak perlu evalsama sekali: lakukan saja parentdir=$(cd -- "$dir" && pwd). Karena cddijalankan dalam subkulit, Anda tidak perlu cdkembali ke tempat kami sebelumnya. Di --sini jika ekspansi $dirdimulai dengan tanda hubung. Ini &&hanya untuk mencegah parentdiragar konten tidak kosong ketika cdtidak berhasil.
gniourf_gniourf
8
Motivasi untuk jawaban lain
Saya suka kode yang sangat singkat, jelas, dan terjamin. Poin bonus jika tidak menjalankan program eksternal, karena pada hari Anda perlu memproses sejumlah besar entri, itu akan terasa lebih cepat.
Prinsip
Tidak yakin dengan jaminan apa yang Anda miliki dan inginkan, jadi tetaplah menawarkan.
Jika Anda memiliki jaminan, Anda dapat melakukannya dengan kode yang sangat singkat. Idenya adalah untuk menggunakan fitur substitusi teks bash untuk memotong garis miring terakhir dan apa pun yang mengikuti.
Jawab dari kasus sederhana hingga yang lebih kompleks dari pertanyaan awal.
Jika jalur dijamin berakhir tanpa garis miring (masuk dan keluar)
Jika jalur input dapat berakhir dengan nol atau satu garis miring (tidak lebih) dan Anda ingin jalur keluaran berakhir tanpa garis miring
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/do
P_ENDNOSLASH="${P%/}"; echo "${P_ENDNOSLASH%/*}"done/home/smith/Desktop/home/smith/Desktop
Jika jalur input mungkin memiliki banyak garis miring luar dan Anda ingin jalur keluaran berakhir tanpa garis miring
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/ \
/home/smith///Desktop////Test//do
P_NODUPSLASH="${P//\/*(\/)/\/}"
P_ENDNOSLASH="${P_NODUPSLASH%%/}"
echo "${P_ENDNOSLASH%/*}";done/home/smith/Desktop/home/smith/Desktop/home/smith/Desktop
Jawaban yang fantastis. Karena sepertinya dia sedang mencari cara untuk melakukan ini dari dalam skrip (temukan direktori skrip saat ini dan itu adalah induknya dan lakukan sesuatu yang relatif terhadap tempat skrip itu tinggal) ini adalah jawaban yang bagus dan Anda bahkan dapat memiliki kontrol lebih besar atas apakah input memiliki garis miring atau tidak dengan menggunakan ekspansi parameter terhadap ${BASH_SOURCE[0]}yang akan menjadi path lengkap ke skrip jika tidak bersumber melalui sourceatau ..
dragon788
7
Jika /home/smith/Desktop/Test/../itu yang Anda inginkan:
maaf, maksud saya seperti script bash, saya punya variabel dengan path file
YTKColumba
Menjalankan kode itu memberi saya kesalahan bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'"). Kode tertaut juga salah.
Michael Hoffman
coba jalankan dirname Testdari direktori Test.
Jon Egeland
1
Bergantung pada apakah Anda membutuhkan jalur absolut, Anda mungkin ingin mengambil langkah ekstra:
local lookFor_ parent_ switch_ i_
lookFor_="$1"#if it is not a file, we need the grand parent[-f "$lookFor_"]|| switch_="/.."#length of search string
i_="${#lookFor_}"#remove string one by one until it make sens for the systemwhile["$i_"-ge 0]&&[!-d "${lookFor_:0:$i_}"];do
let i_--done#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")"#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_
"
jika karena alasan apapun Anda tertarik dalam menjelajahi sampai jumlah tertentu direktori Anda juga bisa melakukan: nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd). Ini akan memberikan 3 direktori orang tua
..
', tapi mungkin itu tidak sesuai yang Anda pikirkan.Jawaban:
Bekerja jika ada garis miring, juga.
sumber
parentdir=$(dirname `pwd`)
... tapi apa yang "terlihat di sini " rusak. Inilah solusinya:
sumber
Cukup gunakan
echo $(cd ../ && pwd)
saat bekerja di direktori yang direktori induknya ingin Anda ketahui. Rantai ini juga memiliki manfaat tambahan karena tidak memiliki garis miring.sumber
echo
sini.Jelas direktori induk diberikan hanya dengan menambahkan nama file dot-dot:
Tetapi Anda harus menginginkan jalur yang diselesaikan (jalur absolut tanpa komponen jalur titik-titik):
Masalah dengan jawaban teratas yang digunakan
dirname
, adalah bahwa mereka tidak berfungsi ketika Anda memasukkan jalur dengan titik-titik:Ini lebih kuat :
Anda bisa memberinya makan
/home/smith/Desktop/Test/..
, tetapi juga jalur yang lebih kompleks seperti:EDIT: Jika tidak berhasil, periksa apakah Anda
cd
belum dimodifikasi, seperti yang biasa dilakukan,sumber
eval
TIDAK bagus jika ada kemungkinan parsing input pengguna yang dapat menempatkan Anda di tempat yang tidak Anda harapkan atau menjalankan hal-hal buruk terhadap sistem Anda. Bisakah Anda menggunakanpushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/null
bukaneval
?eval
sama sekali: lakukan sajaparentdir=$(cd -- "$dir" && pwd)
. Karenacd
dijalankan dalam subkulit, Anda tidak perlucd
kembali ke tempat kami sebelumnya. Di--
sini jika ekspansi$dir
dimulai dengan tanda hubung. Ini&&
hanya untuk mencegahparentdir
agar konten tidak kosong ketikacd
tidak berhasil.Motivasi untuk jawaban lain
Saya suka kode yang sangat singkat, jelas, dan terjamin. Poin bonus jika tidak menjalankan program eksternal, karena pada hari Anda perlu memproses sejumlah besar entri, itu akan terasa lebih cepat.
Prinsip
Tidak yakin dengan jaminan apa yang Anda miliki dan inginkan, jadi tetaplah menawarkan.
Jika Anda memiliki jaminan, Anda dapat melakukannya dengan kode yang sangat singkat. Idenya adalah untuk menggunakan fitur substitusi teks bash untuk memotong garis miring terakhir dan apa pun yang mengikuti.
Jawab dari kasus sederhana hingga yang lebih kompleks dari pertanyaan awal.
Jika jalur dijamin berakhir tanpa garis miring (masuk dan keluar)
Jika jalur dijamin berakhir dengan tepat satu tebasan (masuk dan keluar)
Jika jalur input dapat berakhir dengan nol atau satu garis miring (tidak lebih) dan Anda ingin jalur keluaran berakhir tanpa garis miring
Jika jalur input mungkin memiliki banyak garis miring luar dan Anda ingin jalur keluaran berakhir tanpa garis miring
sumber
${BASH_SOURCE[0]}
yang akan menjadi path lengkap ke skrip jika tidak bersumber melaluisource
atau.
.Jika
/home/smith/Desktop/Test/../
itu yang Anda inginkan:seperti yang terlihat di sini .
sumber
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")
. Kode tertaut juga salah.dirname Test
dari direktoriTest
.Bergantung pada apakah Anda membutuhkan jalur absolut, Anda mungkin ingin mengambil langkah ekstra:
sumber
gunakan ini:
export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
jika Anda ingin direktori induk ke-4export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
jika Anda ingin direktori induk ke-3export MYVAR="$(dirname "$(dirname $PWD)")"
jika Anda ingin direktori induk ke-2sumber
jelek tapi efisien
{
}
sumber
Dimulai dari ide / komentar Charles Duffy - 17 Des '14 jam 5:32 pada topik Dapatkan nama direktori saat ini (tanpa path lengkap) dalam skrip Bash
sumber
jika karena alasan apapun Anda tertarik dalam menjelajahi sampai jumlah tertentu direktori Anda juga bisa melakukan:
nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd)
. Ini akan memberikan 3 direktori orang tuasumber