मैं एक ब्लैकलिस्ट फ़ाइल से तार पढ़ रहा हूं जिसमें फ़ाइलें और फ़ोल्डर्स हैं जिन्हें हटा दिया जाना चाहिए। यह साधारण फ़ाइल नामों के लिए काम करता है, लेकिन वाइल्डकार्ड के साथ नहीं।

उदा. अगर मैं शेल rm -rf !(abc|def) टाइप करता हूं तो यह इन दो फाइलों को छोड़कर सभी को हटा देता है। इस स्ट्रिंग !(abc|def) को ब्लैकलिस्ट में डालने पर यह काम नहीं करता है, क्योंकि स्ट्रिंग का मूल्यांकन नहीं किया जाता है।

इसलिए मैंने eval का उपयोग करने की कोशिश की, लेकिन यह अपेक्षा के अनुरूप काम नहीं करता है।

#!/bin/bash
# test pattern (normally read from blacklist file)
LINE="!(abc|def)"

# output string
echo "$LINE"

# try to expand this wildcards
eval "ls $LINE"

# try with subshell
( ls $LINE )

मैं इसे कैसे काम कर सकता हूं?

3
user3150128 5 जुलाई 2017, 12:10
'मैं एक ब्लैकलिस्ट फ़ाइल से तार पढ़ रहा हूँ' : कैसे ? आपका कोड यह हिस्सा नहीं दिखाता है।
 – 
sjsam
5 जुलाई 2017, 12:23
इसके लिए -regex और -delete के साथ ढूंढें का उपयोग करके आप बेहतर हैं।
 – 
Raman Sailopal
5 जुलाई 2017, 12:26
एसजेएसएम, मैंने यह हिस्सा नहीं दिखाया क्योंकि इसका मेरी समस्या से कोई लेना-देना नहीं है। समस्या को पुन: उत्पन्न करना आसान बनाने के लिए मैंने एक स्ट्रिप डाउन स्क्रिप्ट तैयार की।
 – 
user3150128
5 जुलाई 2017, 13:31

1 उत्तर

सबसे बढ़िया उत्तर

सबसे अधिक संभावना है, गैर-संवादात्मक शेल के लिए extglob शेल विकल्प बंद है (जैसे आपकी स्क्रिप्ट चलती है)।

आपको कुछ चीजें बदलनी होंगी:

#!/bin/bash

# Turn on extglob shell option
shopt -s extglob

line='!(abc|def)'

echo "$line"

# Quoting suppresses glob expansion; this will not work
ls "$line"

# Unquoted: works!
ls $line

आपको करना होगा

  • extglob शेल विकल्प चालू करें
  • $line का उपयोग नहीं किया गया: उद्धरण ग्लोब विस्तार को दबा देता है, जो कि लगभग हमेशा वांछित है, लेकिन यहां नहीं

ध्यान दें कि मैं लोअरकेस चर नामों का उपयोग करता हूं। अपरकेस शेल और पर्यावरण चर के लिए आरक्षित है; लोअरकेस का उपयोग करने से नाम संघर्ष की संभावना कम हो जाती है (देखें POSIX युक्ति , चौथा पैराग्राफ)।

साथ ही, यहां eval की जरूरत नहीं है।

5
Benjamin W. 5 जुलाई 2017, 12:23
अच्छा यह इस मुद्दे को हल कर सकता है। हालांकि, मैं यह देखने के लिए उत्सुक हूं कि ऑप ब्लैकलिस्ट फ़ाइल से उन फ़ाइल नामों को कैसे पढ़ रहा है। :)
 – 
sjsam
5 जुलाई 2017, 12:27
2
हां, एक्स/वाई समस्या भी हो सकती है;)
 – 
Benjamin W.
5 जुलाई 2017, 12:28
1
आप यह उल्लेख करना चाह सकते हैं कि आप for का उपयोग करके बैश सरणी चर (जैसे a=($line) या पुनरावृति (पोर्टेबल) में विस्तार कर सकते हैं, लेकिन eval और प्रश्न में दिखाए गए उप-दृष्टिकोण से बचने के लिए, जो व्यक्तिगत फ़ाइल नामों की पहचान खो देते हैं। यह -- के उपयोग पर कुछ मार्गदर्शन के लायक भी हो सकता है ताकि नामों के साथ समस्याओं से बचा जा सके जो कमांड विकल्पों की तरह दिखते हैं।
 – 
Toby Speight
5 जुलाई 2017, 12:41
आप शायद IFS= को भी सेट करके शब्द विभाजन को अक्षम करना चाहते हैं
 – 
chepner
5 जुलाई 2017, 14:26
मैं इन सभी के मान्य बिंदुओं से सहमत हूं। मेरा उत्तर प्रश्न में दिखाई गई विशिष्ट समस्या को संबोधित करता है, क्योंकि प्रश्न यह नहीं दिखाता कि पैटर्न कैसे पढ़े जाते हैं। जबकि मैं उत्तरों में सर्वोत्तम प्रथाओं को दिखाने के लिए हूं, मुझे नहीं लगता कि प्रत्येक उत्तर कैच-ऑल हो सकता है और उन चीजों को इंगित कर सकता है जो गलत हो सकती हैं यदि प्रश्न उनका उल्लेख भी नहीं करता है।
 – 
Benjamin W.
5 जुलाई 2017, 14:40