2009-02-04 12 views
51

मैं निम्न आदेश को चलाने के लिए कोशिश कर रहा हूँ:xargs बैश ​​को नहीं पहचानता उपनाम

find . -iname '.#*' -print0 | xargs -0 -L 1 foobar 

जहां "foobar" एक उपनाम या समारोह (मेरी Bashrc फाइल में परिभाषित मेरे मामले में है, यह एक समारोह है जो एक पैरामीटर लेता है)। जाहिर है xargs इन चीजों को पहचानने के रूप में नहीं पहचानता है। क्या इसका समाधान करने का कोई चालाक तरीका है?

+1

इस कारण मैं बजाय मेरी ~/बिन फ़ोल्डर पर स्क्रिप्ट बनाने में से एक है बैश उपनाम बनाना। इस तरह, मैं अपने उपनामों को किसी भी खोल से उपयोग कर सकता हूं: बाश, जेडएसएच, आईपैथॉन या फिश। – Yoo

+2

यहां एक समान (हालांकि समान नहीं है) प्रश्न है: http: // stackoverflow।कॉम/प्रश्न/9 7 9 453/कैसे-कर-i-use-aliased-command-with-xargs –

उत्तर

34

को पैरामीटर के रूप में है कि स्क्रिप्ट के नाम से पारित के बाद से केवल आपका इंटरैक्टिव खोल केवल उपनामों के बारे में जानता है, क्यों न केवल xargs के माध्यम से बाहर निकलने के बिना उपनाम चलाएं?

find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done 

आप सुनिश्चित करें कि आपके फ़ाइल नाम उन में नई-पंक्तियों की जरूरत नहीं है कर रहे हैं (ick, इसलिए वे? होगा), तो आप इस

find . -iname '.#*' -print | while read -r i; do foobar "$i"; done 

या बस find -iname '.#*' | ... को आसान बनाने में कर सकते हैं, के बाद से डिफ़ॉल्ट निर्देशिका . है और डिफ़ॉल्ट कार्रवाई -print है।

एक और विकल्प:

IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done 

कह बैश कि शब्द (डिफ़ॉल्ट: IFS=$' \t\n') नई-पंक्तियों पर ही विभाजित कर रहे हैं। आपको इसके साथ सावधान रहना चाहिए, यद्यपि; कुछ स्क्रिप्ट एक बदले $IFS के साथ अच्छी तरह से सामना नहीं करते हैं।

+1

यह उत्तर उत्तर दे रहा है क्यों हम xargs का उपयोग नहीं कर सकते हैं और हम उपनाम के साथ xargs का उपयोग कैसे कर सकते हैं। –

+0

यह उत्तर हमें xargs का उपयोग करने के लिए * विकल्प * देता है। एक उत्तर के लिए जो काम करता है * xargs * का उपयोग करके, संबंधित प्रश्न में @ कैम का जवाब देखें: http://stackoverflow.com/questions/979453/how-can-i-use-aliased-commands-with-xargs (जो नाथन फ़ेलमैन ऊपर से जुड़ा हुआ) –

1

मैं आमतौर पर इस तरह लगता है का उपयोग करें:

find . -iname '' -exec cmd '{}' \; 

'{}' फ़ाइल नाम, और \ के साथ प्रतिस्थापित किया जाएगा; निष्पादन श्रृंखला को समाप्त करने के लिए आवश्यक है। हालांकि, कि अगर आपकी समारोह के साथ काम नहीं करता है, तो आप पार्टी के माध्यम से इसे चलाने के लिए आवश्यकता हो सकती है:

find .. |sed -e "s/.*/cmd '&'/"|bash 

ढूँढें प्रिंट प्रत्येक फ़ाइल एक लाइन पर, SED सिर्फ अपने आदेश के साथ इस उपसर्ग, और फिर पाइप यह पार्टी की योजना बनाई निष्पादन के लिए। क्या होगा यह देखने के लिए पहले | bash को छोड़ें।

+0

यदि आप एक नया जीएनयू ढूंढ रहे हैं, तो '-exec cmd' {} '+' का उपयोग करें: यह xargs की तरह अधिक कार्य करता है उसमें यह प्रत्येक फ़ाइल के लिए एक नया cmd निष्पादित करने के बजाय एक रन में एक साथ तर्कों को बैच करेगा। – ephemient

+0

मुझे लगता है कि अगर उसका फ़ंक्शन एकाधिक पैरामीटर लेने में सक्षम था तो वह xargs के लिए -L 1 विकल्प की आपूर्ति नहीं करेगा ... – Alnitak

+0

ओह, यही है-एल क्या करता है? मैंने इसे नहीं देखा, और मैं उस उद्देश्य के लिए उपयोग करता हूं। – ephemient

4

इसका कारण यह है xargsकार्यक्रम अपने पैरामीटर के रूप में दिए गए exec करने में सक्षम हो जाने की उम्मीद काम नहीं करता।

चूंकि foobar आपके मामले में केवल bash उपनाम या फ़ंक्शन निष्पादित करने के लिए कोई प्रोग्राम नहीं है।

हालांकि यह find द्वारा लौटाए गए प्रत्येक फ़ाइल के लिए bash शुरू कर शामिल है, यदि आप एक छोटे खोल स्क्रिप्ट इस प्रकार लिख सकते हैं:

#!/bin/bash 
. $(HOME)/.bashrc 
func $* 

और फिर xargs

+0

मुझे उस स्क्रिप्ट को कहां रखना चाहिए ताकि * इसे * xargs' द्वारा पहचाना जा सके? –

+0

@ निकवोलिनकिन जहां भी आप चाहें, जब तक कि यह '$ पाथ' में हो या उसका स्थान सीधे 'xargs' पर दे। – Alnitak

+0

ठीक है, स्पष्टीकरण के लिए धन्यवाद। –

8

बैश आप का उपयोग करना भी आर्ग की संख्या निर्दिष्ट कर सकते हैं ताकि तरह अपना उपनाम (या समारोह) के लिए पारित किया जा रहा:

alias myFuncOrAlias='echo' # alias defined in your ~/.bashrc, ~/.profile, ... 
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0 
echo arg1 arg2 | xargs bash -cil 'myFuncOrAlias "[email protected]"' arg0 
संबंधित मुद्दे