Belirli bir dosya varsa rasgele bir ileti görüntüleme komutu


11

Belirli bir dosya varsa “Evet” mesajını görüntüleme komutu var mı? Dosya yoksa işlevsellik vermeye gerek yoktur.

Yanıtlar:


25

Bu basit Bash tek astarını kullanın:

if [ -e FILENAME ] ; then echo Yes ; fi

-eTrue için onay değerlendirir FILENAMEvar, hayır ne olduğunu fark (dosya, dizin, bağlantı, cihaz, ...).

Yalnızca normal dosyaları kontrol etmek istiyorsanız, -fbunun yerine @Arronical'in dediği gibi kullanın .


18
[ -e FILENAME ] && echo Yes
Zeb McCorkle

@ZebMcCorkle Doğru, bu da işe yarıyor. Bunu ayrı bir cevap olarak gönderebilirsiniz.
Bayt Komutanı

3
Eğer FILENAMEbir değişken genişleme veya herhangi özel karakterler içeren, ardından alıntı unutmayın. örneğin bir senaryoda [ -e "$1" ] && echo Yes,.
Peter Cordes

@PeterCordes kullanıyorsanız bash kullanabilirsiniz [[ve ]]değişkeni alıntılamak yerine.
Holloway

1
@Holloway: evet, ancak bazen sadece POSIX sh gerektiren taşınabilir komut dosyaları yazmanız gerekir. Bu yüzden bunu düşürmek ve bash cevabını yükseltmek yerine bunun güvenli bir versiyonunu verdim. Ayrıca [[ ]], içerideki açılımları teklif etmenin bir sorun olmadığını unutmayın , her zaman alıntı yapmak, [[ ]]operatörün içindeki özel kuralları hatırlamayan yeni başlayanlar veya aritmetik bağlamlar için iyi bir alışkanlıktır .
Peter Cordes

10

Bu basit komut dosyasını kullanabilirsiniz:

#!/bin/bash

if [[ -f $1 ]]; then
    echo "Yes"
    exit 0
else
    exit 1
fi

Farklı kaydedin file-exists.sh. Ardından, Terminal'e yazın chmod +x file-exists.sh.

Kontrol etmek istediğiniz dosyayla ./file-exists.sh FILEdeğiştirdiğiniz gibi kullanın: FILEörneğin:

./file-exists.sh file.txt

Eğer file.txtmevcutsa, YesTerminaline basılacak ve program durumuyla 0 (başarılı) ile çıkılacak. Dosya yoksa, hiçbir şey yazdırılmaz ve program durum 1 (çıkış) ile çıkar.

exitKomutu neden eklediğimi merak ediyorsanız okumaya devam edin ...


Komutta ne var exit?

exitnormal işlem sonlandırmasına neden olur. Bunun anlamı, temel olarak: komut dosyasını durdurur. Onu çağıran komut dosyasının çıkış durumu olacak isteğe bağlı (sayısal) bir parametreyi kabul eder.

Bu çıkış durumu, diğer komut dosyalarınızın komut file-existsdosyanızı kullanmasını sağlar ve dosyanın var olup olmadığını bilmenin yoludur.

Bunu kullanmak için koyar basit bir örnek bu betiğidir (farklı kaydedin file-exists-cli.sh):

#!/bin/bash

echo "Enter a filename and I will tell you if it exists or not: "
read FILE
# Run `file-exists.sh` but discard any output because we don't need it in this example
./file-exists.sh $FILE &>> /dev/null
# #? is a special variable that holds the exit status of the previous command
if [[ $? == 0 ]]; then
    echo "$FILE exists"
else
    echo "$FILE does not exist"
fi

Her zamanki yapın chmod +x file-exists-cli.shve çalıştırın: ./file-exists-cli.sh. Bunun gibi bir şey göreceksiniz:

Dosya var ( exit 0):

➜  ~ ./file-exists-cli.sh 
Enter a filename and I will tell you if it exists or not: 
booleans.py
booleans.py exists

Dosya mevcut değil ( exit 1):

➜  ~ ./file-exists-cli.sh
Enter a filename and I will tell you if it exists or not: 
asdf
asdf does not exist

2
İyi, ama gibi değişken referanslar teklif edecek "$1". İçinde beyaz boşluk varsa, tırnak işaretleri olmadan kırılır ve başka kötü şeyler olabilir.
Joe

9

Komut satırındaki bash kabuğunda.

if [[ -f /path/to/file ]]; then echo "Yes"; fi

Bu, bash koşullu işlecini kullanır ve -fdosyanın var olup olmadığını ve normal bir dosya olup olmadığını kontrol eder. Dizinler ve bağlantılar da dahil olmak üzere herhangi bir dosyayı test etmek istiyorsanız kullanın -e.

Bu, bash koşulları için harika bir kaynaktır.


1
Neden çift parantez?
Bayt Komutanı

1
testOrijinal biçiminde bir hayran değilim , aşırıya kaçtığını biliyorum, ama benim alışkanlığım.
Arronical

7
@ByteCommander: çift ayraçlar genellikle tek ayraçlardan daha iyidir. Kabuk sözdiziminin bir parçasıdırlar ( [genellikle yerleşik olanı çağırmak için komutu çağırmak yerine ). Tekli ayraç sürümünün tutarsızlıklarını ve dilsiz davranışlarını düzeltirler. [Yerleşik uyumluluk için kalır, ancak yeni bash kodunda kullanmak için iyi bir neden görmüyorum. (Eski kabuklarda veya başka bir şeyde çalışabilecek POSIX uyumlu komut dosyaları yazmanız gerekiyorsa, bu farklıdır.)
Nick Matteo

@kundor: Çoğunlukla adil olmak için, " [genellikle yerleşik olanı çağırır" şüpheli. type -a [benim için "kabuk yerleşik", sonra " /usr/bin/[."
wchargin

1
@wchargin: Korkarım ne elde ettiğinizi anlamıyorum. Kişisel typesonuçları Hayır dedim neyi teyit görünüyor?
Nick Matteo

5

İstediğinizi yapmak için en kısa komut:

test -e FILENAME && echo Yes

test -everilen adın dosya sisteminde olup olmadığını test eder. (Yalnızca test -fnormal dosyalarla sınırlamak için kullanabilirsiniz . Daha man testfazla bilgi için bakın .)

Verilen koşul true olarak değerlendirilirse, testbaşarılı bir çıkış durumu döndürür (aksi takdirde hata durumu döndürür). İki komutu kullanarak birleştiriyoruz, &&yani "önceki komut bir başarı durumundan çıkarsa bir sonraki komutu yürüt". Bir sonraki komut sadece Yesstandart çıktıya yazdırılır ; etkileşimli bir kabuk durumunda, terminalde.

Bu, bir ififadenin ek metinsel materyalini önler , ancak aynı sonucu verir. Kullanılması &&(veya onun karşısında ||sadece tek bir komut söz konusu olduğunda birlikte komutları kravat) iyi çalışıyor. Tek bir komutun çıkış durumuna yanıt olarak tek bir komut yürütmekten daha fazlasını yapmak istiyorsanız, ifsözdizimini kullanmak çok daha kolay okunabilir hale gelir.

Diğer cevaplarda da belirtildiği gibi, eşdeğer ifstil yapısı şöyle olacaktır:

if test -e FILENAME; then echo Yes; fi

Veya alternatif olarak:

if test -e FILENAME
then
    echo Yes
fi

Bu amaçlar için [ve testeşdeğerdir, bunun dışında [bir sonlandırma talep eder ].


4

Bu tür soruları kaplamak için birden çok yol var ve bir tane daha var: bayrağı olan findkomutu kullanın -exec. Dosya yolu, find /etcdizini ayarlayan ve -name FILENAMEdosya adını (duh!) Belirten iki kısma ayrılabilir . yalnızca dizinle çalışmaya -maxdepthdevam edecek ve alt dizinlere inmeyecekfind/etc

adminx@L455D:~$ find /etc -maxdepth 1  -name passwd -exec printf "YES\n" \;
YES
adminx@L455D:~$ find /etc -maxdepth 1  -name passwd1 -exec printf "YES\n" \;
adminx@L455D:~$ 

Başka bir yol, yoluyla stat:

adminx@L455D:~$ stat /etc/passwd1 &>/dev/null && echo YES
adminx@L455D:~$ stat /etc/passwd &>/dev/null && echo YES
YES

Ve alternatif olarak python ile:

>>> import os
>>> if os.stat('/etc/passwd'): 
...    print 'YES'
... 
YES
>>> if os.stat('/etc/passwd1'): 
...    print 'YES'
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '/etc/passwd1'

Veya kısa bir komut satırı alternatifi:

 python -c "from os.path import exists; print 'Yes' if exists('/etc/fstab') else '' "
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.