खाली शेल वैरिएबल का उपयोग करते समय एक त्रुटि जारी करें


22

कभी-कभी मैं $PROJECT_HOME/*प्रोजेक्ट में सभी फ़ाइलों को हटाने के लिए उपयोग करता हूं । जब पर्यावरण चर, PROJECT_HOMEसेट नहीं किया जाता है (क्योंकि मैंने किया था suऔर नए उपयोगकर्ता के पास यह पर्यावरण चर सेट नहीं है), यह रूट फ़ोल्डर से सभी फ़ाइलों को हटाना शुरू कर देता है। यह सर्वनाश है।

bashजब मैं शेल में अपरिभाषित पर्यावरण चर का उपयोग करता हूं, तो मैं त्रुटि फेंकने के लिए कैसे कॉन्फ़िगर कर सकता हूं ?


5
set -uजो चाहोगे, करोगे।
congonglm

क्या आप इसे उत्तर के रूप में बना सकते हैं?

2
बेशक आप अपने वर्जन को खाली स्ट्रिंग्स में इनिशियलाइज़ नहीं करेंगे। [ -z "$VAR" ]एक असिंचित के साथ VARभी काम करता है। आरंभीकरण सिर्फ अवांछनीय व्यवहार दिखाने के लिए था - मेरा कहना है, यदि आपके संस्करण कभी भी खाली तारों के लिए आरंभीकृत नहीं होते हैं, तो आप जिस भी तरीके से और आप rm -r "$PROJECT_HOME"/*गलती से भरोसा करते हैं set -u, आपको "एपोकैलिक" व्यवहार मिलेगा। IHMO, आपके कंप्यूटर की संपूर्ण सामग्री की सुरक्षा करने के लिए क्षमा करने से सुरक्षित रहना बेहतर है। set -uसुरक्षित नहीं है।
PSkocik

3
"यह बेहद लंबा है"? आपको खतरनाक संचालन को मैन्युअल रूप से करने के लिए सुविधाजनक तरीके की तलाश में नहीं होना चाहिए । इसके बजाय, आपको एक फ़ंक्शन, उपनाम, या स्क्रिप्ट बनाना चाहिए जो आप चाहते हैं; इस मामले में, @ PSkocik की सुझाई गई कमांड से एक उपनाम में बनाना सुरक्षित और सुविधाजनक दोनों होगा ।
काइल स्ट्रैंड

1
यदि उपयोगकर्ता सेट करता है तो क्या होगा PROJECT_HOME=/etc? बस एक खाली मूल्य के लिए जाँच करना प्रलय को रोकने के लिए पर्याप्त नहीं है। रूट के रूप में चलने के दौरान आपको अविश्वसनीय उपयोगकर्ताओं से चर का उपयोग नहीं करना चाहिए।
बमर

जवाबों:


27

POSIX शेल में, आप सेट -u का उपयोग कर सकते हैं :

#!/bin/sh

set -u
: "${UNSET_VAR}"

या पैरामीटर विस्तार का उपयोग :

: "${UNSET_VAR?Unset variable}"

आपके मामले में, आपको सेट पर विफल लेकिन खाली चर के :?बजाय उपयोग करना चाहिए ?:

rm -rf -- "${PROJECT_HOME:?PROJECT_HOME empty or unset}"/*

17
[ -z "$PROJECT_HOME" ] || rm -r "$PROJECT_HOME"/*

यह भी इस मामले में जहां पकड़ेगा PROJECT_HOME है निर्धारित करते हैं लेकिन कुछ भी नहीं है।

उदाहरण:

1) यह आपके सिस्टम पर आपके द्वारा हटाए जा सकने वाले सभी चीज़ों को हटा देगा /( अंदर डॉटफ़ाइल्स को रोकना (आमतौर पर कोई भी नहीं है)):

set -u
PROJECT_HOME=
rm -r "$PROJECT_HOME"/*

2) यह कुछ नहीं करेगा:

PROJECT_HOME=
[ -z "$PROJECT_HOME" ] || rm -r "$PROJECT_HOME"/* 

पूरी तरह से अपने प्रोजेक्ट को घर से हटाने और इसे फिर से बनाने का एक और विकल्प हो सकता है (यदि आप भी डॉटफ़ाइल्स से छुटकारा पाना चाहते हैं):

#no apocalyptic threats in this scenario
rm -r "$PROJECT_HOME"
mkdir "$_" 

1
-zठीक है, लेकिन चूंकि $PROJECT_HOMEयह एक निर्देशिका माना जाता है, शायद -dबेहतर होगा। [[ -d $PROJECT_HOME ]] && rm -r "$PROJECT_HOME"
कोजिरो

2
यदि PROJECT_HOME एक nondirectory पर सेट है, तो यह एक नॉनकास्ट्रोफिक त्रुटि है, संभवतः एक टाइपो के कारण। -dजाँच करें कि त्रुटि को छिपाने जाएगा। मुझे लगता है कि यह बेहतर है अगर यह आगे बढ़ता है rmऔर rmइसके बारे में ज़ोर से शिकायत करता है।
PSkocik

2
यदि PROJECT_HOME सेट है, लेकिन नाम निर्देशिका नहीं है, तो [[ -d $PROJECT_HOME ]] && rm -r "$PROJECT_HOME"चुपचाप कुछ भी नहीं करेगा। लेकिन [[ -z $PROJECT_HOME ]] || rm -r "$PROJECT_HOME"चुपचाप "$ PROJECT_HOME" हटा देगा, भले ही यह एक ऐसी फ़ाइल हो जो निर्देशिका नहीं है। त्रुटि संदेश प्राप्त करना कभी कोई समस्या नहीं है:if [[ -d $PROJECT_HOME ]]; then rm -r "$PROJECT_HOME"; else printf '%s is not a directory\n' "$PROJECT_HOME" >&2; fi
kojiro

1
अब "दुर्घटनावश" ​​सेट PROJECT_HOME="/."...
हेगन वॉन एटिजन

1
@HagenvonEitzen अगर PROJECT_HOME रूट पर सेट है, तो PROJECT_HOME खाली करने वाली प्रक्रिया रूट को खाली कर देगी। यह अपेक्षित और पूरी तरह से उचित व्यवहार है। और आपको उस अंतिम डॉट की भी आवश्यकता नहीं है।
PSkocik

0

ऐसा करने का एक और तरीका:

rm -r "${somevar:-/tmp/or_this_if_somevar_is_empty}"/*

कई परिवर्तनशील विकल्प हैं, ऊपर वाला जब "somevar" खाली होता है (और उस स्थिति में इसे हटाने का प्रयास करता है /tmp/or_this_if_somevar_is_empty/*)


1
या: rm -fr ${ENV_VAR:?suitably caustic message here}/*, लेकिन यह अभी भी लायक चेकिंग कि मूल्य रूट निर्देशिका के लिए नक्शे नहीं है, यह देखते हुए वहाँ सरल परीक्षण को नष्ट करने का कई तरीके हैं कि हो सकता है: //, /.., /usr/who/../.., ...
जोनाथन Leffler

हाँ। यदि आप एक पैरामीटर विस्तार का उपयोग करने जा रहे हैं, तो आप उसी का
डिजिटल ट्रॉमा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.