जब स्रोत फ़ाइल मौजूद नहीं होती है, तो 'cp' कमांड को एक एरर कैसे दें?


59

मैं मैक ओएस एक्स का उपयोग कर रहा हूं। मैं इस तरह एक बिल्ड स्क्रिप्ट के लिए cp कमांड के साथ कुछ फाइलों को कॉपी करने की कोशिश कर रहा हूं।

cp ./src/*/*.h ./aaa

लेकिन अगर ./src निर्देशिका में कोई .h फ़ाइल नहीं है, तो यह कमांड त्रुटि देता है। कमांड को एरर कैसे करें? (साइलेंट फेलियर) त्रुटि बिल्ड रिजल्ट को विफल कर देती है, लेकिन मैं केवल तब कॉपी करना चाहता हूं जब केवल कुछ हेडर फाइल हों।

जवाबों:


69

यदि आप त्रुटि संदेश के बारे में बात कर रहे हैं, तो आप इसे बिट बकेट में भेजकर दबा सकते हैं:

cp ./src/*/*.h ./aaa 2>/dev/null

यदि आप निकास कोड और त्रुटि संदेश को दबाना चाहते हैं:

cp ./src/*/*.h ./aaa 2>/dev/null || :

8
:इस संदर्भ में इसका क्या अर्थ है, यह बताना अच्छा होगा ।
Piotr Dobrogost

23
@PiotrDobrogost: बैश और कुछ अन्य गोले में बृहदान्त्र एक शून्य उपयोगिता (नो-ऑप) है। यह POSIX द्वारा निर्दिष्ट किया गया है । चूँकि यह हमेशा सच होता है, इसलिए इसका उपयोग यहाँ एक असफल (जो वांछित होना चाहिए) के निकास कोड को दबाने के लिए किया जाता है । इसके बजाय शेल बिल्ड का उपयोग किया जा सकता है और अधिक पठनीय होगा। cptrue
डेनिस विलियमसन


1
यह भी अन्य त्रुटियों (स्रोत / गंतव्य निर्देशिका मौजूद नहीं है, स्रोत फ़ाइल मौजूद है, लेकिन पढ़ने योग्य नहीं है, डिस्क भरा हुआ, केवल पढ़ने के लिए फाइल सिस्टम, आईओ त्रुटि, पर ध्यान नहीं देगा cpमें किया जा रहा नहीं PATHकिसी भी तरह ...)
व्लादिमीर Panteleev

अप्रत्याशित टोकन के पास सिंटैक्स त्रुटि `||
२०:५२

13

आप कुछ की तलाश में हैं

if [ -e file ]
 then cp file /somewhere
fi

(दुर्भाग्य से, वह -fविकल्प नहीं है जिसे आप देख रहे हैं।)

यदि आप एक ग्लोब से मेल खाना चाहते हैं, तो यह काम नहीं करेगा; findइसके बजाय उपयोग करें , उदाहरण के लिए:

find ./src -name \*.h -exec cp {} ./destination \;

ध्यान दें कि इस तरह के दृष्टिकोण के साथ एक संभावित TOCTOU मुद्दा है (जैसे कि यदि आप उपयोग करते हैं set -e, और फ़ाइल [और cpचालान के बीच गायब हो जाती है , तो आपकी स्क्रिप्ट क्रैश हो जाएगी)।
व्लादिमीर पेंटेलेव

9

पुराना सवाल है, लेकिन अभी भी दूसरों के लिए प्रासंगिक हो सकता है।
यदि आपको cp का उपयोग करने की आवश्यकता नहीं है , तो आप rsync के साथ प्रयास कर सकते हैं।
किसी स्रोत से गंतव्य निर्देशिका तक सभी फ़ाइलों की प्रतिलिपि बनाने के लिए, चलाएँ:

rsync -avzh --ignore-errors /path/to/source /path/to/destination

रुपीक्स अधिकांश यूनिक्स जैसी प्रणालियों जैसे लिनक्स, मैक ओएस एक्स या फ्रीबीएसडी के साथ आता है।


4
आप पैरामीटर को जोड़ते हुए cp के बजाय rsync का उपयोग कर सकते हैं --ignore-missing-args: rsync -av --ignore-missing-args ./src/*/*.h ./aaaइसका यह फायदा है --ignore-errorsकि केवल जिन त्रुटियों को अनदेखा किया गया है, वे स्रोत फ़ाइलों से संबंधित हैं जो मौजूद नहीं हैं। --ignore-errorsहर त्रुटि के साथ नजरअंदाज किया जाता है, जो खतरनाक हो सकता है। यह भी ध्यान रखें कि यह पैरामीटर काफी हाल ही में है, इसलिए यह rsync के पुराने संस्करणों में मौजूद नहीं हो सकता है।
jesjimher

6

परिणाम को सही साबित करने से यह सुनिश्चित होता है कि कमांड हमेशा सफल होगा। मैंने इसे लिनक्स पर आज़माया है लेकिन किसी मैक ओएस पर नहीं:

cp ./src/*/*.h ./aaa | true

5
साधारण पाइप |हमेशा चलाया जाता है जबकि ||केवल एक त्रुटि के मामले में किया जाता है। और trueआमतौर पर एक द्विआधारी होता है जबकि कोलन :एक बिल्डिन होता है और एक पीआईडी ​​का उपभोग नहीं करता है।
ott--

MacOS पर एक बैश स्क्रिप्ट - Yosemite जिसमें "cp ./src/*/*.h//aaa" कमांड है। यदि .h फाइलें मौजूद नहीं हैं, तो कमांड एरर नहीं करती है।
विवेक

2

आप सही त्रुटि स्थिति को बाध्य कर सकते हैं। एक समारोह के साथ:

$ cpalways () { cp $1 $2 2>/dev/null ; return 0 ; }

निम्नलिखित को देखते हुए:

$ ls foo bar baz
ls: baz: No such file or directory
bar foo

नियमित कॉपी में त्रुटि होगी। यह 1 का निकास स्थिति लौटाएगा।

$ cp baz bar ; echo $?
cp: baz: No such file or directory
1

यदि हम ऊपर cpalways () फ़ंक्शन का उपयोग करते हैं, तो कोई भी त्रुटि छिपी होगी:

$ cpalways baz bar ; echo $?
0
$ cpalways foo bar ; echo $?
0
$ cpalways baz bar ; echo $?
0
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.