Saya menulis skrip yang dipanggil saat pengguna masuk dan memeriksa apakah folder tertentu ada atau ada symlink yang rusak. (Ini pada sistem Mac OS X, tetapi pertanyaannya murni bash).
Itu tidak elegan, dan tidak berfungsi, tetapi sekarang ini terlihat seperti ini:
#!/bin/bash
# Often users have a messed up cache folder -- one that was redirected
# but now is just a broken symlink. This script checks to see if
# the cache folder is all right, and if not, deletes it
# so that the system can recreate it.
USERNAME=$3
if [ "$USERNAME" == "" ] ; then
echo "This script must be run at login!" >&2
exit 1
fi
DIR="~$USERNAME/Library/Caches"
cd $DIR || rm $DIR && echo "Removed misdirected Cache folder" && exit 0
echo "Cache folder was fine."
Inti masalahnya adalah bahwa ekspansi tilde tidak berfungsi seperti yang saya inginkan.
Katakanlah saya memiliki nama pengguna george
, dan folder rumahnya adalah /a/path/to/georges_home
. Jika, pada suatu shell, saya mengetik:
cd ~george
itu membawa saya ke direktori yang sesuai. Jika saya mengetik:
HOME_DIR=~george
echo $HOME_DIR
Ini memberi saya:
/a/path/to/georges_home
Namun, jika saya mencoba menggunakan variabel, itu tidak berfungsi:
USERNAME="george"
cd ~$USERNAME
-bash: cd: ~george: No such file or directory
Saya sudah mencoba menggunakan tanda kutip dan backticks, tetapi tidak tahu bagaimana membuatnya berkembang dengan baik. Bagaimana saya membuat ini bekerja?
Tambahan
Saya hanya ingin memposting skrip saya yang sudah selesai (sungguh, itu tidak seburuk pekerjaan yang sedang berjalan di atas!) Dan mengatakan bahwa itu tampaknya berfungsi dengan benar.
#!/bin/bash
# Often users have a messed up cache folder -- one that was redirected
# but now is just a broken symlink. This script checks to see if
# the cache folder is all right, and if not, deletes it
# so that the system can recreate it.
#set -x # turn on to help debug
USERNAME=$3 # Casper passes the user name as parameter 3
if [ "$USERNAME" == "" ] ; then
echo "This script must be run at login!" >&2
exit 1 # bail out, indicating failure
fi
CACHEDIR=`echo $(eval echo ~$USERNAME/Library/Caches)`
# Show what we've got
ls -ldF "$CACHEDIR"
if [ -d "$CACHEDIR" ] ; then
# The cache folder either exists or is a working symlink
# It doesn't really matter, but might as well output a message stating which
if [ -L "$CACHEDIR" ] ; then
echo "Working symlink found at $CACHEDIR was not removed."
else
echo "Normal directory found at $CACHEDIR was left untouched."
fi
else
# We almost certainly have a broken symlink instead of the directory
if [ -L "$CACHEDIR" ] ; then
echo "Removing broken symlink at $CACHEDIR."
rm "$CACHEDIR"
else
echo "Abnormality found at $CACHEDIR. Trying to remove." >&2
rm -rf "$CACHEDIR"
exit 2 # mark this as a bad attempt to fix things; it isn't clear if the fix worked
fi
fi
# exit, indicating that the script ran successfully,
# and that the Cache folder is (almost certainly) now in a good state
exit 0
Itu karena ia akan menyertakan ~ george dalam tanda kutip tunggal ketika ditetapkan sebagai variabel.
set -x
berguna untuk debugging.Hapus pengaturan kutip ketika
DIR
dan shell akan berkembang ketika mengatur variabel, yang akan memberi Anda kinerja yang Anda inginkan.sumber
Bash memiliki variabel yang diekspor bawaan untuk nama pengguna dan direktori home pengguna. Jika Anda memanggil skrip Anda saat pengguna masuk dari skrip mereka
~/.bash_profile
misalnya, Anda tidak perlu meneruskan nilai sebagai argumen ke skrip Anda.Anda dapat menggunakan
$USER
dan$HOME
karena sudah disetel dan tersedia di lingkungan skrip Anda karena ditandai sebagai diekspor. Saya pikir ekspansi tilde dimaksudkan untuk lebih kenyamanan baris perintah daripada sesuatu yang digunakan dalam skrip.Mungkin lebih dapat diandalkan untuk mendapatkan direktori home pengguna dengan salah satu cara berikut:
atau
Juga,
exit 0
menunjukkan kesuksesan. Di satu sisi, proses Anda berhasil menghapus direktori, tetapi fakta bahwa itu perlu dihapus adalah semacam kesalahan. Bagaimanapun, jika Andaexit 0
pada titik ini Anda tidak akan dapat membedakannya ketika skrip keluar setelah finalecho
karena kode keluar kemungkinan besar akan nol.sumber
||
dan&&
sebagai kontrol aliran (mengganti pernyataan jika) adalah gaya yang buruk.exit n
di akhir skrip jika gagal juga merupakan kesalahan. Nol menunjukkan keberhasilan dan Anda dapat menggunakan nomor bukan nol yang berbeda untuk menunjukkan berbagai jenis kesalahan (terserah Anda untuk menentukan maknanya untuk tujuan Anda sendiri). Jika Anda tidak perlu membedakan satu jenis kesalahan dari yang lain, makaexit 1
sama baiknya dengan yang digunakan dalam semua kasus untuk menunjukkan suatu kesalahan umumMenilai dari jalurnya
$HOME/Library/Caches
, ini adalah Mac OS X, begitudscl
juga teman Anda.Seperti disebutkan di atas,
bash
apakah itu untuk Anda, dan jika itu adalah Mac, Anda dapat menjaminbash
akan tersedia (dan karenanya Anda tidak perlu khawatir tentang orang yang benar-benar/bin/sh
tidak bisa mengatasinya).sumber
dscl /Search read /Users/$USERNAME NFSHomeDirectory | cut -f 2 -d " "
tampaknya tepat untuk mendapatkan informasi yang saya cari.