यदि कोई कमांड एक खाली स्ट्रिंग आउटपुट करता है तो मैं कैसे परीक्षण कर सकता हूं?
ifne
है। joeyh.name/code/moreutils
यदि कोई कमांड एक खाली स्ट्रिंग आउटपुट करता है तो मैं कैसे परीक्षण कर सकता हूं?
ifne
है। joeyh.name/code/moreutils
जवाबों:
पहले, यह सवाल पूछा गया था कि किसी निर्देशिका में फाइलें हैं या नहीं। निम्न कोड प्राप्त होता है, लेकिन बेहतर समाधान के लिए rsp का उत्तर देखें ।
कमांड मान वापस नहीं करते हैं - वे उन्हें आउटपुट करते हैं। आप कमांड प्रतिस्थापन का उपयोग करके इस आउटपुट को कैप्चर कर सकते हैं ; उदा $(ls -A)
। आप इस तरह से बैश में एक गैर-खाली स्ट्रिंग के लिए परीक्षण कर सकते हैं:
if [[ $(ls -A) ]]; then
echo "there are files"
else
echo "no files found"
fi
ध्यान दें कि मैंने इसके -A
बजाय प्रयोग किया है -a
, क्योंकि यह प्रतीकात्मक वर्तमान ( .
) और माता-पिता ( ..
) निर्देशिका प्रविष्टियों को छोड़ देता है ।
नोट: जैसा कि टिप्पणियों में बताया गया है, कमांड प्रतिस्थापन नए सिरे को पीछे नहीं खींचता है । इसलिए, यदि कमांड केवल नई रूपरेखाओं का उत्पादन करता है, तो प्रतिस्थापन कुछ भी नहीं पकड़ेगा और परीक्षण गलत वापस आ जाएगा। हालांकि बहुत संभावना नहीं है, यह उपरोक्त उदाहरण में संभव है, क्योंकि एक भी नईलाइन एक वैध फ़ाइल नाम है! इस उत्तर में अधिक जानकारी ।
यदि आप जांचना चाहते हैं कि कमांड सफलतापूर्वक पूरा हुआ है, तो आप निरीक्षण कर सकते हैं $?
, जिसमें अंतिम कमांड का निकास कोड (सफलता के लिए शून्य, विफलता के लिए गैर-शून्य) है। उदाहरण के लिए:
files=$(ls -A)
if [[ $? != 0 ]]; then
echo "Command failed."
elif [[ $files ]]; then
echo "Files found."
else
echo "No files found."
fi
अधिक जानकारी यहाँ ।
if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]; then ...; fi
मेरे मूल सुधार के सुझाव के लिए netj का धन्यवाद :if [[ $(ls -A | wc -c) -ne 0 ]]; then ...; fi
यह एक पुराना प्रश्न है लेकिन मुझे कम से कम दो चीजें दिखाई देती हैं जिनमें कुछ सुधार की आवश्यकता होती है या कम से कम कुछ स्पष्टीकरण की आवश्यकता होती है।
पहली समस्या मैं देख रहा हूँ कि यहाँ उपलब्ध कराए गए अधिकांश उदाहरण केवल काम नहीं करते हैं । वे कमांड ls -al
और ls -Al
कमांड - दोनों का उपयोग करते हैं , जो खाली निर्देशिकाओं में गैर-खाली तारों का उत्पादन करते हैं। वे उदाहरण हमेशा रिपोर्ट करते हैं कि जब कोई नहीं होता है तब भी फाइलें होती हैं ।
इस कारण से आपको बस का उपयोग करना चाहिए ls -A
- कोई भी -l
स्विच का उपयोग क्यों करना चाहता है जिसका अर्थ है "लंबी सूची प्रारूप का उपयोग करें" जब आप चाहते हैं कि कोई भी आउटपुट है या नहीं, वैसे भी परीक्षण है?
इसलिए यहां ज्यादातर उत्तर गलत हैं।
दूसरी समस्या यह है कि जब है कुछ जवाब ठीक से काम (उन है कि नहीं है का उपयोग करें ls -al
या ls -Al
लेकिन ls -A
बजाय) वे सब कुछ इस तरह करते हैं:
इसके बजाय मैं क्या करने का सुझाव दूंगा:
using head -c1
उदाहरण के लिए, इसके बजाय:
if [[ $(ls -A) ]]
मै इस्तेमाल करूंगा:
if [[ $(ls -A | wc -c) -ne 0 ]]
# or:
if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]
के बजाय:
if [ -z "$(ls -lA)" ]
मै इस्तेमाल करूंगा:
if [ $(ls -lA | wc -c) -eq 0 ]
# or:
if [ $(ls -lA | head -c1 | wc -c) -eq 0 ]
और इसी तरह।
छोटे आउटपुट के लिए यह एक समस्या नहीं हो सकती है लेकिन बड़े आउटपुट के लिए अंतर महत्वपूर्ण हो सकता है:
$ time [ -z "$(seq 1 10000000)" ]
real 0m2.703s
user 0m2.485s
sys 0m0.347s
इसकी तुलना करें:
$ time [ $(seq 1 10000000 | wc -c) -eq 0 ]
real 0m0.128s
user 0m0.081s
sys 0m0.105s
और भी बेहतर:
$ time [ $(seq 1 10000000 | head -c1 | wc -c) -eq 0 ]
real 0m0.004s
user 0m0.000s
sys 0m0.007s
विल वॉसडेन के जवाब से अद्यतन उदाहरण:
if [[ $(ls -A | wc -c) -ne 0 ]]; then
echo "there are files"
else
echo "no files found"
fi
नेटज के सुझावों के बाद फिर से अपडेट किया गया :
if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]; then
echo "there are files"
else
echo "no files found"
fi
Jakeonfire द्वारा अतिरिक्त अद्यतन :
grep
यदि कोई मैच नहीं है, तो एक विफलता के साथ बाहर निकल जाएगा। हम इसका लाभ सिंटैक्स को थोड़ा सरल बनाने के लिए ले सकते हैं:
if ls -A | head -c1 | grep -E '.'; then
echo "there are files"
fi
if ! ls -A | head -c1 | grep -E '.'; then
echo "no files found"
fi
यदि आप जिस कमांड का परीक्षण कर रहे हैं वह कुछ व्हाट्सएप का उत्पादन कर सकता है जिसे आप एक खाली स्ट्रिंग के रूप में व्यवहार करना चाहते हैं, तो इसके बजाय:
| wc -c
आप उपयोग कर सकते हैं:
| tr -d ' \n\r\t ' | wc -c
या साथ head -c1
:
| tr -d ' \n\r\t ' | head -c1 | wc -c
या कुछ इस तरह का।
सबसे पहले, एक कमांड का उपयोग करें जो काम करता है ।
दूसरा, रैम में अनावश्यक भंडारण और संभावित विशाल डेटा के प्रसंस्करण से बचें।
उत्तर में यह निर्दिष्ट नहीं किया गया कि आउटपुट हमेशा छोटा होता है इसलिए बड़े आउटपुट की संभावना पर भी विचार किया जाना चाहिए।
[[ $(... | head -c | wc -c) -gt 0 ]]
या [[ -n $(... | head -c1) ]]
बेहतर है क्योंकि wc -c
कमांड के पूरे आउटपुट का उपभोग करना होगा।
if [ -z "$(ls -lA)" ]; then
echo "no files found"
else
echo "There are files"
fi
यह कमांड चलाएगा और जांच करेगा कि लौटा हुआ आउटपुट (स्ट्रिंग) एक शून्य लंबाई है या नहीं। आप अन्य झंडों के लिए 'परीक्षण' मैनुअल पृष्ठों की जांच करना चाह सकते हैं ।
जिस तर्क की जाँच की जा रही है, उसके चारों ओर "" का उपयोग करें, अन्यथा खाली परिणामों में एक सिंटैक्स त्रुटि होगी, क्योंकि कोई दूसरा तर्क नहीं है (दिए गए जाँचने के लिए)!
नोट: जो ls -la
हमेशा लौटता है .
और ..
इसलिए इसका उपयोग करने से काम नहीं चलेगा, ls मैनुअल पेज देखें । इसके अलावा, जबकि यह सुविधाजनक और आसान लग सकता है, मुझे लगता है कि यह आसानी से टूट जाएगा। एक छोटी स्क्रिप्ट / एप्लिकेशन लिखना जो परिणाम के आधार पर 0 या 1 देता है, बहुत अधिक विश्वसनीय है!
$(
$(
उन लोगों के लिए जो एक सुरुचिपूर्ण, बैश संस्करण-स्वतंत्र समाधान चाहते हैं (वास्तव में अन्य आधुनिक गोले में काम करना चाहिए) और जो लोग त्वरित कार्यों के लिए वन-लाइनर्स का उपयोग करना पसंद करते हैं। ये रहा!
ls | grep . && echo 'files found' || echo 'files not found'
(उल्लिखित टिप्पणियों में से एक के रूप में ध्यान दें, ls -al
और वास्तव में, बस -l
और -a
सभी कुछ वापस कर देंगे, इसलिए मेरे उत्तर में मैं सरल का उपयोग करता हूंls
grep -q ^
इसके बजाय उपयोग करते हैं, तो newline वर्णों का भी मिलान किया जाएगा, और grep मानक आउटपुट के लिए कुछ भी प्रिंट नहीं करेगा। इसके अलावा, इसके इनपुट स्ट्रीम के समाप्त होने की प्रतीक्षा करने के बजाय, यह किसी भी इनपुट को प्राप्त करते ही बाहर निकल जाएगा।
ls -A
आप डॉट फ़ाइलों को शामिल करने के लिए (या निर्देशिका) चाहते हैं
-z string
True if the length of string is zero.
-n string
string
True if the length of string is non-zero.
आप आशुलिपि संस्करण का उपयोग कर सकते हैं:
if [[ $(ls -A) ]]; then
echo "there are files"
else
echo "no files found"
fi
string
एक पर्यायवाची है -n string
।
जैसा कि जॉन लिन ने टिप्पणी की, ls -al
हमेशा आउटपुट (के लिए .
और ..
) होगा। आप ls -Al
इन दो निर्देशिकाओं से बचना चाहते हैं ।
आप उदाहरण के लिए कमांड के आउटपुट को शेल वेरिएबल में डाल सकते हैं:
v=$(ls -Al)
एक पुराना, गैर-घोंसला, संकेतन है
v=`ls -Al`
लेकिन मैं नेस्टेबल नोटेशन पसंद करता हूं $(
...)
आप परीक्षण कर सकते हैं कि वैरिएबल खाली नहीं है
if [ -n "$v" ]; then
echo there are files
else
echo no files
fi
और आप दोनों को जोड़ सकते हैं if [ -n "$(ls -Al)" ]; then
मैं अनुमान लगा रहा हूं कि आप ls -al
कमांड का आउटपुट चाहते हैं , इसलिए बैश में, आपके पास कुछ ऐसा होगा:
LS=`ls -la`
if [ -n "$LS" ]; then
echo "there are files"
else
echo "no files found"
fi
ls
को कभी भी निष्पादित नहीं किया जा रहा है। आप केवल जाँचते हैं कि चर LS
का विस्तार गैर-रिक्त है या नहीं।
-a
स्विच कोई सामग्री वापस कभी नहीं होगा (फ़ाइलें हैं या नहीं यानी, यह सामग्री वापस आ जाएगी) है के बाद से वहाँ हमेशा निहित .
और ..
निर्देशिका प्रस्तुत करते हैं।
अब तक दिए गए सभी उत्तर उन आदेशों से निपटते हैं जो एक गैर-रिक्त स्ट्रिंग को समाप्त और आउटपुट करते हैं।
अधिकांश निम्न इंद्रियों में टूट जाते हैं:
yes
)।तो इन सभी मुद्दों को ठीक करने के लिए, और निम्नलिखित प्रश्न का कुशलतापूर्वक जवाब देने के लिए,
यदि कोई कमांड एक खाली स्ट्रिंग आउटपुट करता है तो मैं कैसे परीक्षण कर सकता हूं?
आप उपयोग कर सकते हैं:
if read -n1 -d '' < <(command_here); then
echo "Command outputs something"
else
echo "Command doesn't output anything"
fi
तुम भी एक आदेश एक निश्चित समय के भीतर एक गैर खाली स्ट्रिंग आउटपुट है, का उपयोग कर परीक्षण के लिए के रूप में तो कुछ समय समाप्ति जोड़ सकते हैं read
के -t
विकल्प। जैसे, 2.5 सेकंड के समय के लिए:
if read -t2.5 -n1 -d '' < <(command_here); then
echo "Command outputs something"
else
echo "Command doesn't output anything"
fi
टिप्पणी। यदि आपको लगता है कि आपको यह निर्धारित करने की आवश्यकता है कि क्या कोई कमांड एक गैर-खाली स्ट्रिंग को आउटपुट करता है, तो आपको बहुत ही XY समस्या है।
seq 1 10000000
, seq 1 20
, और printf""
)। एकमात्र रीडअप इस रीड अप्रोच को जीत नहीं पाया, यह -z "$(command)"
एक खाली इनपुट के दृष्टिकोण के साथ था । फिर भी, यह केवल लगभग 10-15% तक खो देता है। वे आसपास भी टूटने लगते हैं seq 1 10
। भले ही, -z "$(command)"
दृष्टिकोण इतना धीमा हो जाता है क्योंकि इनपुट आकार बढ़ता है कि मैं इसे किसी भी चर-आकार के इनपुट के लिए उपयोग करने से बचूंगा।
यहाँ एक वैकल्पिक दृष्टिकोण है जो कुछ कमांड के std-out और std-ir को एक अस्थायी फ़ाइल लिखता है, और फिर यह देखने के लिए जाँच करता है कि क्या वह फ़ाइल खाली है। इस दृष्टिकोण का एक लाभ यह है कि यह दोनों आउटपुट को कैप्चर करता है, और सब-शेल या पाइप का उपयोग नहीं करता है। ये बाद के पहलू महत्वपूर्ण हैं क्योंकि वे बैश निकास से निपटने में बाधा डाल सकते हैं (जैसे यहां )
tmpfile=$(mktemp)
some-command &> "$tmpfile"
if [[ $? != 0 ]]; then
echo "Command failed"
elif [[ -s "$tmpfile" ]]; then
echo "Command generated output"
else
echo "Command has no output"
fi
rm -f "$tmpfile"
कभी-कभी आप आउटपुट को सहेजना चाहते हैं, अगर यह गैर-खाली है, तो इसे किसी अन्य कमांड में पास करें। यदि हां, तो आप कुछ का उपयोग कर सकते हैं
list=`grep -l "MY_DESIRED_STRING" *.log `
if [ $? -eq 0 ]
then
/bin/rm $list
fi
इस प्रकार, rm
यदि सूची खाली है , तो कमांड लटकाएगी नहीं।