Soru Bash'de normal bir dosyanın bulunup bulunmadığını nasıl anlarım?


Bir dosya olup olmadığını görmek için aşağıdaki komut dosyasını kullandım:

#!/bin/bash

FILE=$1     
if [ -f $FILE ]; then
   echo "File $FILE exists."
else
   echo "File $FILE does not exist."
fi

Dosyanın yapılıp yapılmadığını kontrol etmek için kullanılacak doğru sözdizimi nedir? değil var olmak?

#!/bin/bash

FILE=$1     
if [ $FILE does not exist ]; then
   echo "File $FILE does not exist."
fi

2518
2018-03-12 14:48


Menşei


Bunu buldum bash koşullu ifadelerin listesi çok kullanışlı. - Saulius Žemaitaitis
Çok tembel bir insan olduğum için, tipik olarak şu aptalca geçici çözümü yapıyorum: if [ -f $FILE ]; then; else; echo "File $FILE does not exist."; fi; Muhtemelen bu sorunun cevabını buldum ve bunu daha doğru bir şekilde yapmayı öğrendim. :) - Alderath
Çatışmış olmak için, "normal dosya" demeniz gerekir, çünkü çoğu UNIX / POSIX dokümanı genel olarak tüm dosya sistemi girişlerine genel olarak "dosya" türlerine atıfta bulunur, örneğin sembolik bir bağlantı bir dosya tipidir. , düzenli dosya, dizin, blok özel, karakter özel, soket, vb. - kevinarpe
Eğer test etmek istiyorsanız bir şey var, kullan -e. -Dizinler, symlinks vb. - Benubird
Güvende olmak için, her zaman dosya adlarını beyaz boşluk ile doğru şekilde işlemek için çift tırnak kullanın. FILE=$1-> FILE="$1" ve if [ -f $FILE ];-> if [ -f "$FILE" ]; - kevinarpe


Cevaplar:


Ölçek komut ([ burada) ünlem işareti olan bir “değil” mantıksal işleve sahiptir (diğer birçok dile benzer). Bunu dene:

if [ ! -f /tmp/foo.txt ]; then
    echo "File not found!"
fi

3529
2018-03-12 14:50



"2 dosyadan herhangi biri yoksa" için doğru sözdizimini bulmak için biraz uğraştım. Aşağıdaki ikisi de çalışır: if [ ! \( -f "f1" -a -f "f2" \) ] ; then echo MISSING; fi  if [ ! -f "f1" ] || [ ! -f "f2" ] ; then echo MISSING; fi - mivk
@DavidWinterbottom Daha da sulu bir şekilde: [ -f /tmp/foo.txt ] || echo "File not found!" - David W.
Parametre aşağıdakilerden herhangi biri olabilir: -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 - SD.
Bir ifllemede 2 koflul kullanmak isterseniz, -a operatörünü kullan, bu da AND demektir. [[]] Operatörünü kullanırsanız bunun mümkün olduğunu düşünüyorum. - GroundZero
Kullanımda bir asimetri var ! -f ile && kullanmaya karşı -f ile ||. Bu, varolmayan kontrol tarafından döndürülen çıkış kodu ile ilgilidir. Hattınızı daima çıkış kodundan 0 çıkarak çıkarmanız gerekiyorsa (ve bazen bu kısıtlamayı istemiyorsanız), iki yaklaşım birbirinin yerine kullanılamaz. Alternatif olarak, sadece if deyim ve artık varoluş kontrolünüzün çıkış kodu hakkında endişelenmenize gerek yok. - A-B-B


Bash Dosya Testi

-b filename - Özel dosyayı engelle
-c filename - Özel karakter dosyası
-d directoryname - Dizin varlığını kontrol edin
-e filename - Tip (düğüm, dizin, soket vb.) Ne olursa olsun dosya varlığını kontrol edin.
-f filename - Bir dizin değil düzenli dosya varlığını kontrol edin
-G filename - Dosyanın var olup olmadığını kontrol edin ve etkili grup kimliğine aittir
-G filename set-group-id - Dosya varsa ve set-group-id ise doğrudur
-k filename - Yapışkan bit
-L filename - Sembolik bağlantı
-O filename - Dosya varsa ve etkin kullanıcı kimliğine aitse doğrudur
-r filename - Dosyanın okunabilir olup olmadığını kontrol edin
-S filename - Dosya soket olup olmadığını kontrol edin
-s filename - Dosyanın sıfırdan büyük olup olmadığını kontrol edin
-u filename - Dosya set-kullanıcı-kimlik biti ayarlanmış mı kontrol edin
-w filename - Dosyanın yazılabilir olup olmadığını kontrol edin
-x filename - Dosyanın yürütülebilir olup olmadığını kontrol edin

Nasıl kullanılır:

#!/bin/bash
file=./file
if [ -e "$file" ]; then
    echo "File exists"
else 
    echo "File does not exist"
fi 

bir test ifadesi kullanarak reddedilebilir ! Şebeke

#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
    echo "File does not exist"
else 
    echo "File exists"
fi 

429
2018-01-16 14:25



@ 0x90 İsterseniz, gönderimi düzenlemek ve listeye eklemekte özgürsünüz. Galiba demek istedin: -n String - Dizginin uzunluğunun sıfır olup olmadığını kontrol edin. Yoksa demek istiyorsun file1 -nt file2 - Dosya1'in daha yeni olup olmadığını kontrol edin, ardından dosya 2'yi (daha sonra eski için de kullanabilirsiniz) - GroundZero
-N hakkında: 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.html - GroundZero


Bir ifadeyi "!" İle reddedebilirsiniz:

#!/bin/bash
FILE=$1

if [ ! -f "$FILE" ]
then
    echo "File $FILE does not exist"
fi

İlgili adam sayfası man test Veya eşdeğer olarak, man [ - veya help test veya help [ yerleşik bash komutu için.


250
2018-03-12 14:50



İçinde darbe, [ bir yerleşiktir. Böylece ilgili bilgiler daha çok help [... ama bu gösteriyor ki [ için eşanlamlı test Yerleşik, dolayısıyla ilgili bilgi daha çok tarafından elde edilir help test. Ayrıca bkz. Kılavuzdaki Bash Koşullu İfade bölümü. - gniourf_gniourf
@gniourf_gniourf: Evet, ama bash yerleşik [ komut dışına çok benzer davranır [ komut, ya man test veya man [ nasıl çalıştığına dair iyi bir fikir verecektir. - Keith Thompson
@KeithThompson bunun dışında darbe builtin [ harici komuttan daha fazla anahtar var [ sistemimde bulundu ... Genel olarak, belirli bir araca özgü dokümantasyonu okumak daha iyi olduğuna inanıyorum, ve başka bir belirsiz bir ilgili belgelere özel değil. Yanılıyor olabilirim ;) - gniourf_gniourf


[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"

Ayrıca, dosyanın bozuk bir sembolik bağ olması veya normal olmayan bir dosya olması da mümkündür. bir soket, cihaz veya fifo. Örneğin, bozuk bağlantılara bir kontrol eklemek için:

if [[ ! -f $FILE ]]; then
    if [[ -L $FILE ]]; then
        printf '%s is a broken symlink!\n' "$FILE"
    else
        printf '%s does not exist!\n' "$FILE"
    fi
fi

110
2018-03-12 14:52



Testte neden iki "s" olduğunu sorabilir miyim? (ör. [[! -a $ FILE]]). Bir solaris kutusu üzerinde bahsettiğim tüm seçenekleri denedim ve sadece bir tanesi işe yaradı, çok minnettardı, ama neden? - Dimitrios Mistriotis
Çift parantez bir "modern" uzantısıdır; örneğin kelime bölme yapmazlar (boşluklu dosya isimleri gibi) ve hala boş dizeler için çalışırlar: mywiki.wooledge.org/BashFAQ/031 - bw1024
göre tldp.org/LDP/abs/html/fto.html -a -e ile aynıdır. "Kullanımdan kaldırıldı" ve kullanımı önerilmez. Her nasılsa kırık link bağlantısını kontrol etmek için +1 - Luca Borrione
@dimitrismistriotis two "[", zsh & bash tarafından uygulanan bir taşınabilir olmayan eklentidir (farklı şekilde); Genelde mümkün olduğunca kaçınmalısınız. - Good Person
Ben bu BECAUSE kullanılan oy kullanıldı [[. Yaygın olarak kullanılan bir uzantısıdır. Eğer bash kullandığını biliyorsan, kullanmamak için bir sebep yok. Bundan daha az eğilimli olan [. - Michael Potter


Tek bir komutu çalıştırmanız gerekirse kısaltabilirsiniz.

if [ ! -f "$file" ]; then
    echo "$file"
fi

için

test -f "$file" || echo "$file"

veya

[ -f "$file" ] || echo "$file"

80
2017-08-11 09:15



Teşekkürler! Kullanmayan bir alternatife ihtiyaç var [[]] - Jonathan


Aşağıdaki tek astarı yapmayı tercih ederim. POSIX kabuk uyumlu formatı:

$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"

$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"

Komutta yapacağım gibi birkaç komut için:

$  [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}

Bunu yapmaya başladığımda, artık tamamen yazılan sözdizimini nadiren kullanıyorum !!


57
2017-10-18 16:09



Öncelikle, seçilmemiş değişken referanslar hataya eğilimlidir. Dedi ki, nerede diyor herhangi bash manpage [ veya test yerleşik test için olurdu dosya varlığı argüman varsayılan olarak (aksine -e)? Bu belirsiz olmaz mıydı? AFAIK (ve AIUI bölümü "KOŞULLARI İFADE") yaklaşımınız ile test edilen tek şey argümanın boş olmadığı (veya tanımlanmamış) olmasıdır, ki bu durumda, bir totoloji ( $DIR = '' ve $FILE = ''sonra argüman hala '//'). - PointedEars
Kanıt: ls /foosonuç ls: cannot access /foo: No such file or directory. [ /foo ] && echo 42sonuç 42. GNU bash, versiyon 4.2.37 (1) -release (i486-pc-linux-gnu). - PointedEars
@PointedEars: Belirleyemedim -f seçeneği, şu anda bu cevabı yazdım. Açıkçası her zaman kullanabilirsiniz -eemin değilseniz, düzenli bir dosya olacak. Ek olarak, tüm senaryolarımda bu yapıları alıntılarım, yeterli bir kanıtlama olmaksızın bunu sunmuş olmalıyım. - TechZilla
ACK. Ama muhtemelen bir linerin if-else problemini çözemeyeceğini biliyorsunuzdur: [ $condition ] && if_true || if_false hataya eğilimli. Her halükarda buluyorum [ ! -f "$file" ] && if_not_exists daha kolay okumak ve anlamak [ -f "$file" ] || if_not_exists. - PointedEars


Dosya varlığını test etmek için, parametre aşağıdakilerden herhangi biri olabilir:

-e: Returns true if file exists (regular file, directory, or symlink)
-f: Returns true if file exists and is a regular file
-d: Returns true if file exists and is a directory
-h: Returns true if file exists and is a symlink

Aşağıdaki tüm testler normal dosyalar, dizinler ve symlink'lere uygulanır:

-r: Returns true if file exists and is readable
-w: Returns true if file exists and is writable
-x: Returns true if file exists and is executable
-s: Returns true if file exists and has a size > 0

Örnek komut dosyası:

#!/bin/bash
FILE=$1

if [ -f "$FILE" ]; then
   echo "File $FILE exists"
else
   echo "File $FILE does not exist"
fi

36
2017-12-19 12:47