Saya telah menggunakan skrip berikut untuk melihat apakah ada file:
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File $FILE exists."
else
echo "File $FILE does not exist."
fi
Apa sintaks yang benar untuk digunakan jika saya hanya ingin memeriksa apakah file tersebut tidak ada?
#!/bin/bash
FILE=$1
if [ $FILE does not exist ]; then
echo "File $FILE does not exist."
fi
if [ -f $FILE ]; then; else; echo "File $FILE does not exist."; fi;
Mungkin lebih baik saya menemukan pertanyaan ini dan belajar untuk melakukannya dengan cara yang lebih tepat. :)-e
. -f tidak akan mengambil direktori, symlink, dll.FILE=$1
->FILE="$1"
danif [ -f $FILE ];
->if [ -f "$FILE" ];
Jawaban:
The uji perintah (
[
di sini) memiliki "tidak" operator logis yang merupakan tanda seru (mirip dengan banyak bahasa lain). Coba ini:sumber
if [ ! \( -f "f1" -a -f "f2" \) ] ; then echo MISSING; fi
if [ ! -f "f1" ] || [ ! -f "f2" ] ; then echo MISSING; fi
[ -f /tmp/foo.txt ] || echo "File not found!"
-e: Returns true value, if file exists
-f: Return true value, if file exists and regular file
-r: Return true value, if file exists and is readable
-w: Return true value, if file exists and is writable
-x: Return true value, if file exists and is executable
-d: Return true value, if exists and is a directory
! -f
dengan&&
versus penggunaan-f
dengan||
. Ini ada hubungannya dengan kode keluar yang dikembalikan oleh pemeriksaan tidak ada. Jika Anda membutuhkan baris Anda untuk selalu keluar dengan bersih dengan kode keluar 0 (dan kadang-kadang Anda tidak ingin kendala ini), kedua pendekatan tidak dapat dipertukarkan. Atau, cukup gunakanif
pernyataan dan Anda tidak perlu lagi khawatir tentang kode keluar dari pemeriksaan non-keberadaan Anda.Pengujian File Bash
-b filename
- Blok file khusus-c filename
- File karakter khusus-d directoryname
- Periksa keberadaan direktori-e filename
- Periksa keberadaan file, terlepas dari jenis (node, direktori, socket, dll.)-f filename
- Periksa keberadaan file biasa bukan direktori-G filename
- Periksa apakah file ada dan dimiliki oleh ID grup yang efektif-G filename set-group-id
- Benar jika file ada dan diatur-grup-id-k filename
- Sticky bit-L filename
- Tautan simbolik-O filename
- Benar jika file ada dan dimiliki oleh id pengguna yang efektif-r filename
- Periksa apakah file dapat dibaca-S filename
- Periksa apakah file soket-s filename
- Periksa apakah file adalah soket - Periksa apakah file bukan nol ukuran-u filename
- Periksa apakah file set-user-id bit diatur-w filename
- Periksa apakah file dapat ditulisi-x filename
- Periksa apakah file dapat dieksekusiCara Penggunaan:
Sebuah ekspresi tes dapat dinegasikan dengan menggunakan
!
operator yangsumber
-n String
- Periksa apakah panjang string tidak nol. Atau maksud Andafile1 -nt file2
- Periksa apakah file1 lebih baru dari file 2 (Anda juga dapat menggunakan -ot untuk yang lebih tua)The unary operator -z tests for a null string, while -n or no operator at all returns True if a string is not empty.
~ ibm.com/developerworks/library/l-bash-test/index.htmlAnda dapat meniadakan ekspresi dengan "!":
Halaman manual yang relevan adalah
man test
atau, setara,man [
- atauhelp test
atauhelp [
untuk perintah bash bawaan.sumber
[
adalah builtin. Jadi informasi yang relevan agak diperoleh olehhelp [
... tetapi ini menunjukkan bahwa[
ini adalah sinonim untuktest
builtin, maka informasi yang relevan agak diperoleh olehhelp test
. Lihat juga bagian Ekspresi Bersyarat Bash dalam manual .[
berperilaku sangat mirip dengan[
perintah eksternal , jadi salah satuman test
atauman [
akan memberi Anda ide bagus tentang cara kerjanya.[
memiliki lebih banyak sakelar daripada perintah eksternal yang[
ditemukan pada sistem saya ... Secara umum saya percaya lebih baik membaca dokumentasi khusus untuk alat yang diberikan, dan bukan dokumentasi yang spesifik untuk yang terkait dengan samar lainnya. Tapi saya mungkin salah;)
Juga, mungkin saja file tersebut merupakan tautan simbolik yang rusak, atau file tidak biasa, seperti misalnya soket, perangkat, atau fifo. Misalnya, untuk menambahkan tanda centang untuk symlink yang rusak:
sumber
Perlu disebutkan bahwa jika Anda perlu menjalankan satu perintah, Anda dapat menyingkat
untuk
atau
sumber
Saya lebih suka melakukan one-liner berikut, dalam format yang kompatibel dengan POSIX shell:
Untuk beberapa perintah, seperti yang akan saya lakukan dalam skrip:
Setelah saya mulai melakukan ini, saya jarang menggunakan sintaks yang diketik sepenuhnya !!
sumber
[
atautest
built-in akan menguji keberadaan file dari argumen secara default (sebagai lawan-e
)? Apakah itu tidak ambigu? AFAIK (dan AIUI bagian "EKSPRESI KONDISI") satu-satunya hal yang diuji dengan pendekatan Anda adalah bahwa argumennya tidak kosong (atau tidak terdefinisi), yang dalam hal ini adalah tautologi (biarkan$DIR = ''
dan$FILE = ''
, maka argumennya masih'//'
).ls /foo
hasills: cannot access /foo: No such file or directory
.[ /foo ] && echo 42
, hasil42
. GNU bash, versi 4.2.37 (1) -release (i486-pc-linux-gnu).-f
opsi, saat ini saya menulis jawaban ini. Tentunya Anda selalu bisa menggunakan-e
, jika Anda tidak yakin itu akan menjadi file biasa. Selain itu Dalam semua skrip saya kutip konstruk ini, saya pasti baru saja mengirimkan ini tanpa bukti yang memadai.[ $condition ] && if_true || if_false
rawan kesalahan. Bagaimanapun, saya menemukan[ ! -f "$file" ] && if_not_exists
lebih mudah untuk membaca dan memahami daripada[ -f "$file" ] || if_not_exists
.Untuk menguji keberadaan file, parameter dapat berupa salah satu dari yang berikut:
Semua tes di bawah ini berlaku untuk file biasa, direktori, dan symlink:
Skrip contoh:
sumber
Kamu bisa melakukan ini:
atau
Jika Anda ingin memeriksa file dan folder keduanya, gunakan
-e
opsi alih-alih-f
.-e
mengembalikan true untuk file biasa, direktori, socket, file karakter khusus, blok file khusus dll.sumber
[
utilitas standar di sini.-f
) dan direktori hanyalah dua dari banyak jenis file . Ada juga soket, symlink, perangkat, fifos, pintu ...[ -e
akan menguji keberadaan file (jenis apa pun termasuk reguler, fifo, direktori ...) setelah resolusi symlink .-e
, dia perlu-f
.Anda harus berhati-hati menjalankan
test
variabel yang tidak dikutip, karena mungkin menghasilkan hasil yang tidak diharapkan:Rekomendasi biasanya memiliki variabel yang diuji dikelilingi oleh tanda kutip ganda:
sumber
[ ... ]
.Ada tiga cara berbeda untuk melakukan ini:
Meniadakan status keluar dengan bash (tidak ada jawaban lain yang mengatakan ini):
Atau:
Meniadakan tes di dalam perintah tes
[
(itu adalah cara sebagian besar jawaban sebelum disajikan):Atau:
Bertindak atas hasil tes menjadi negatif (
||
bukan&&
):Hanya:
Ini terlihat konyol (IMO), jangan gunakan kecuali kode Anda harus portabel ke shell Bourne (seperti
/bin/sh
Solaris 10 atau sebelumnya) yang tidak memiliki operator negasi pipa (!
):sumber
! [
dan[ !
?! [
adalah POSIX untuk pipeline 2.9.2 (perintah apa saja)Otherwise, the exit status shall be the logical NOT of the exit status of the last command
dan[ !
POSIX untuk pengujian! expression True if expression is false. False if expression is true.
Jadi, keduanya POSIX, dan dalam pengalaman saya, keduanya didukung secara luas.!
kata kunci yang diperkenalkan oleh shell Korn. Kecuali mungkin untuk Solaris 10 dan lebih tua, Anda tidak mungkin menemukan shell Bourne hari ini.Di
yang
[
perintah melakukanstat()
(tidaklstat()
) system call pada jalur yang disimpan dalam$file
dan mengembalikan benar jika sistem panggilan berhasil dan jenis file sebagai dikembalikan olehstat()
adalah " biasa ".Jadi, jika
[ -f "$file" ]
mengembalikan true, Anda dapat mengetahui bahwa file tersebut memang ada dan merupakan file biasa atau symlink yang akhirnya diputuskan menjadi file biasa (atau setidaknya itu pada saat filestat()
).Namun jika itu mengembalikan false (atau jika
[ ! -f "$file" ]
atau! [ -f "$file" ]
mengembalikan true), ada banyak kemungkinan berbeda:stat()
panggilan sistem mungkin gagal.Singkatnya, seharusnya:
Untuk mengetahui dengan pasti bahwa file tersebut tidak ada, kita perlu
stat()
panggilan sistem untuk kembali dengan kode kesalahanENOENT
(ENOTDIR
memberitahu kita salah satu komponen jalur bukan direktori adalah kasus lain di mana kita dapat memberi tahu file tidak ada di jalur itu). Sayangnya[
perintah itu tidak memberi tahu kami. Ini akan mengembalikan false apakah kode kesalahan ENOENT, EACCESS (izin ditolak), ENAMETOOLONG atau yang lainnya.The
[ -e "$file" ]
tes juga dapat dilakukan denganls -Ld -- "$file" > /dev/null
. Dalam hal ini,ls
akan memberi tahu Anda mengapastat()
gagal, meskipun informasi tidak dapat dengan mudah digunakan secara terprogram:Setidaknya
ls
memberitahu saya itu bukan karena file itu tidak ada yang gagal. Itu karena tidak tahu apakah file itu ada atau tidak. The[
perintah hanya mengabaikan masalah.Dengan
zsh
shell, Anda dapat meminta kode kesalahan dengan$ERRNO
variabel khusus setelah[
perintah gagal , dan mendekode angka itu menggunakan$errnos
array khusus dalamzsh/system
modul:(berhati-hatilah
$errnos
dukungannya rusak dengan beberapa versizsh
ketika dibangun dengan versi terbarugcc
).sumber
Untuk membalik tes, gunakan "!". Itu sama dengan operator logika "bukan" dalam bahasa lain. Coba ini:
Atau ditulis dengan cara yang sedikit berbeda:
Atau Anda bisa menggunakan:
Atau, satukan semuanya:
Yang dapat ditulis (menggunakan operator "dan" saat itu: &&) sebagai:
Yang terlihat lebih pendek seperti ini:
sumber
The
test
hal bisa menghitung juga. Ini bekerja untuk saya (berdasarkan Bash Shell: Periksa File Ada atau Tidak ):sumber
Kode ini juga berfungsi.
sumber
Cara paling sederhana
sumber
Script shell ini juga berfungsi untuk menemukan file di direktori:
sumber
read -p "Enter file name: " -r a
untuk meminta dan membaca. Itu menggunakan tanda kutip di sekitar variabel; itu bagus, tetapi harus dijelaskan. Mungkin lebih baik jika itu menggema nama file. Dan ini memeriksa apakah file itu ada dan tidak kosong (itulah artinya-s
) sedangkan pertanyaannya menanyakan file apa pun, kosong atau tidak (yang-f
lebih sesuai).terkadang mungkin berguna untuk menggunakan && dan || operator.
Seperti di (jika Anda memiliki perintah "test"):
atau
sumber
Jika Anda ingin menggunakan
test
alih-alih[]
, maka Anda dapat menggunakan!
untuk mendapatkan negasi:sumber
Anda juga dapat mengelompokkan beberapa perintah dalam satu liner
[ -f "filename" ] || ( echo test1 && echo test2 && echo test3 )
atau
[ -f "filename" ] || { echo test1 && echo test2 && echo test3 ;}
Jika nama file tidak keluar, hasilnya akan menjadi
Catatan: (...) berjalan dalam subkulit, {...;} berjalan dalam shell yang sama.
Notasi braket keriting hanya bekerja di bash.sumber
sumber