Cara memeriksa apakah ada file dalam skrip shell

176

Saya ingin menulis skrip shell yang memeriksa apakah file tertentu archived_sensor_data.json,, ada, dan jika demikian, menghapusnya. Mengikuti http://www.cyberciti.biz/tips/find-out-if-file-exists-with-conditional-expressions.html , saya sudah mencoba yang berikut ini:

[-e archived_sensor_data.json] && rm archived_sensor_data.json

Namun, ini menimbulkan kesalahan

[-e: command not found

ketika saya mencoba menjalankan test_controllerskrip yang dihasilkan menggunakan ./test_controllerperintah. Apa yang salah dengan kode tersebut?

Kurt Peek
sumber
2
Anda harus mengatur satu atau lebih spasi putih antara membuka braket persegi "[" dan opsi "-e" sama dengan antara nama file dan braket persegi tutup "]"
Konstantin Yaniv

Jawaban:

351

Anda kehilangan ruang yang diperlukan antara braket dan -e:

#!/bin/bash
if [ -e x.txt ]
then
    echo "ok"
else
    echo "nok"
fi
chris01
sumber
12
Saya akhirnya menambahkan dua ruang kosong, satu setelah pembukaan braket persegi dan satu sebelum yang penutupan: [ -e archived_sensor_data.json ] && rm archived_sensor_data.json. Skripnya sepertinya berfungsi sekarang.
Kurt Peek
3
Ini juga berfungsi menggunakan if [ -e "$1" ](argumen input nama file).
Edward
2
Perbedaan utama di sini adalah kenyataan bahwa Anda menggunakan skrip "bash" alih-alih skrip "shell". Perhatikan bahwa baris pertama yang Anda tambahkan adalah #! / Bin / bash, jadi Anda memberi tahu mesin untuk menggunakan "bash" alih-alih sh. Karena dia tidak mengenali argumen itu "-e"
Nick Cuevas
29

Berikut adalah metode alternatif menggunakan ls:

(ls x.txt && echo yes) || echo no

Jika Anda ingin menyembunyikan output apa pun dari lssehingga Anda hanya melihat ya atau tidak, arahkan ulang stdoutdan stderrke /dev/null:

(ls x.txt >> /dev/null 2>&1 && echo yes) || echo no
Philip Kirkbride
sumber
1
Kode ini berarti: "jika lsberhasil, ada file seperti itu, jika tidak, tidak ada". Jika lsgagal, itu tidak berarti file itu hilang. Mungkin ada beberapa kesalahan lainnya. Misalnya, buat file dalam direktori yang dimiliki oleh root dan coba lakukan di lsbawah pengguna biasa. Ini akan gagal dengan Permission denied, yang tidak setara dengan file yang tidak ada.
Tigran
9

Latar belakang untuk rekomendasi solusi saya adalah kisah seorang teman yang, memasuki minggu kedua pekerjaan pertamanya, menghapus setengah build-server clean. Jadi tugas dasarnya adalah mencari tahu apakah ada file, dan jika demikian, mari kita hapus. Tetapi ada beberapa jeram berbahaya di sungai ini:

  • Semuanya adalah file.

  • Script memiliki kekuatan nyata hanya jika mereka menyelesaikan tugas-tugas umum

  • Untuk menjadi umum, kami menggunakan variabel

  • Kami sering menggunakan -f force dalam skrip untuk menghindari intervensi manual

  • Dan juga suka -r rekursif untuk memastikan kami membuat, menyalin, dan menghancurkan tepat waktu.

Pertimbangkan skenario berikut:

Kami memiliki file yang ingin kami hapus: filesexists.json

Nama file ini disimpan dalam variabel

<host>:~/Documents/thisfolderexists filevariable="filesexists.json"

Kami juga memiliki variabel path untuk membuat semuanya benar-benar fleksibel

<host>:~/Documents/thisfolderexists pathtofile=".."

<host>:~/Documents/thisfolderexists ls $pathtofile

filesexists.json  history20170728  SE-Data-API.pem  thisfolderexists

Jadi mari kita lihat apakah -emelakukan apa yang seharusnya. Apakah file-file itu ada?

<host>:~/Documents/thisfolderexists [ -e $pathtofile/$filevariable ]; echo $?

0

Itu benar. Sihir.

Namun, apa yang akan terjadi, jika variabel file tidak sengaja dievaluasi menjadi nuffin '

<host>:~/Documents/thisfolderexists filevariable=""

<host>:~/Documents/thisfolderexists [ -e $pathtofile/$filevariable ]; echo $?

0

Apa? Seharusnya kembali dengan kesalahan ... Dan ini adalah awal dari cerita bagaimana seluruh folder itu terhapus secara tidak sengaja

Alternatifnya bisa dengan menguji secara khusus untuk apa yang kita pahami sebagai 'file'

<host>:~/Documents/thisfolderexists filevariable="filesexists.json"

<host>:~/Documents/thisfolderexists test -f $pathtofile/$filevariable; echo $?

0

Jadi file itu ada ...

<host>:~/Documents/thisfolderexists filevariable=""

<host>:~/Documents/thisfolderexists test -f $pathtofile/$filevariable; echo $?

1

Jadi ini bukan file dan mungkin, kami tidak ingin menghapus seluruh direktori itu

man test memiliki yang berikut untuk dikatakan:

-b FILE

       FILE exists and is block special

-c FILE

       FILE exists and is character special

-d FILE

       FILE exists and is a directory

-e FILE

       FILE exists

-f FILE

       FILE exists and is a regular file

...

-h FILE

       FILE exists and is a symbolic link (same as -L)
Lefty G Balogh
sumber
4

Secara internal, perintah rm harus menguji keberadaan file,
jadi mengapa menambahkan tes lain? Hanya masalah

rm filename

dan itu akan hilang setelah itu, apakah itu ada atau tidak.
Gunakan rm -f adalah Anda tidak ingin ada pesan tentang file yang tidak ada.

Jika Anda perlu mengambil tindakan jika file TIDAK ada, maka Anda harus mengujinya sendiri. Berdasarkan kode contoh Anda, ini tidak terjadi dalam kasus ini.

TG
sumber
1
Ini sebenarnya jawaban yang cukup valid untuk perintah rm. Untuk perintah lain, saya sarankan untuk menguji dengan -e.
warhansen
Kecuali bahwa bukan itu pertanyaannya.
Crayons
1
Pertanyaan yang diajukan adalah sangat banyak, jika Anda membaca seluruh pertanyaan termasuk bagian "... dan (jika demikian) ... menghapusnya".
TG
1

Jika Anda menggunakan NFS, "tes" adalah solusi yang lebih baik, karena Anda dapat menambahkan batas waktu untuk itu, jika NFS Anda turun:

time timeout 3 test -f 
/nfs/my_nfs_is_currently_down
real    0m3.004s <<== timeout is taken into account
user    0m0.001s
sys     0m0.004s
echo $?
124   <= 124 means the timeout has been reached

Konstruk "[-e my_file]" akan membeku sampai NFS berfungsi kembali:

if [ -e /nfs/my_nfs_is_currently_down ]; then echo "ok" else echo "ko" ; fi

<no answer from the system, my session is "frozen">
FCA69
sumber
testdan [identik. Anda dapat menggunakan timeoutdengan [juga, dan testjuga membeku jika hang NFS.
pria lain