मैं एक ही तर्क का उपयोग करके कई कमांड कैसे निष्पादित कर सकता हूं?


16

मुझे आश्चर्य है कि क्या उबंटू टर्मिनल में श्रृंखला क्रियाएं करना संभव है जैसे:

action 1 on objectA . then action 2 on objectA 

बिना ऑब्जेक्ट के नाम को दोहराए बिना।

उदाहरण:

touch file.js && openEditor "$1" 

या कुछ इस तरह का।


ऐसा करने के बहुत सारे तरीके हैं, लेकिन यह आपकी आवश्यकताओं पर निर्भर करता है। क्या वस्तु है? एक पंक्ति ? हम किन कार्यों के बारे में बात कर रहे हैं?
सर्गी कोलोडियाज़नी

धन्यवाद, आमतौर पर एक फ़ाइल प्रभावी रूप से, एक फ़ोल्डर भी हो सकती है
HoCo_

3
यहाँ, &बैकग्राउंड में "टच" कमांड भेजेगा। यदि आप चाहते हैं कि "संपादक को खोलें यदि स्पर्श सफल हुआ", तो आप &&इसके बजाय चाहते हैं
ग्लेन जैकमैन

आप इस पद से क्यों टकरा रहे हैं? आपको पहले ही बहुत सारे उत्तर मिल चुके हैं और एक भी स्वीकार कर लिया गया है।
मूरू

जवाबों:


27

बैश हिस्ट्री एक्सपेंशन के साथ , आप !#:nउदाहरण के लिए वर्तमान कमांड लाइन के nth शब्द का उल्लेख कर सकते हैं

$ touch foobar && ls -l !#:1
touch foobar && ls -l foobar
-rw-rw---- 1 steeldriver steeldriver 0 Jun 20 14:54 foobar

$ touch foo bar && ls -l !#:2
touch foo bar && ls -l bar
-rw-rw-r-- 1 steeldriver steeldriver 12 Jun 20 14:58 bar

क्या मैं पूछ सकता हूं कि आप किस बैश संस्करण का उपयोग कर रहे हैं?
सर्गी कोलोडियाज़नी

@SergiyKolodyazhnyy यह हैGNU bash, version 4.3.48(1)-release
स्टीलड्राइवर

5
आप शब्दों की एक श्रृंखला भी नामित कर सकते हैं :touch foo bar && ls -l !#:1-2
ग्लेन जैकमैन

1
!जब आप एक संवादात्मक खोल में होते हैं तो @HoCo_ वर्ण इतिहास विस्तार अभिव्यक्ति का परिचय देता है - यह आपके द्वारा लिखी जाने वाली फ़्लाइट कमांड लाइन हेरफेर के लिए है, और यह गैर-संवादात्मक स्क्रिप्ट के अंदर अक्षम है
Steeldriver

1
@HoCo_ एक स्क्रिप्ट में आपको पता होना चाहिए कि तर्क समय से पहले क्या है - इसलिए उदाहरण के लिए आप बस कर सकते हैंarg1=file.js; touch "$arg1" && openEditor "$arg1"
स्टीलड्रॉपर

12

एक सामान्य उपयोग के मामले के लिए एक आसान शॉर्टकट है। अपने उदाहरण में आप कर रहे हैं:

$ touch file.js
$ openEditor <alt>+<.>

दूसरी कमांड में, ट्रिक को + के openEditorबाद (इसके बाद एक स्पेस के साथ) लिखना है । यह अंतिम कमांड के अंतिम तर्क को सम्मिलित करेगा , जो कि है । (यदि यह किसी कारण से काम नहीं करता है , तो भी काम करना चाहिए।)Alt.file.jsAltEsc

चूंकि अक्सर "ऑब्जेक्ट" वास्तव में पिछले कमांड का अंतिम तर्क होता है, इसलिए इसका अक्सर उपयोग किया जा सकता है। यह याद रखना आसान है और सहज रूप से उपयोग किए गए शेल शॉर्टकट के आपके सेट में एकीकृत होगा।

इसके साथ आप जो कुछ कर सकते हैं, उसका एक पूरा समूह है, यहां संभावनाओं के बारे में एक गहन लेख है: /programming/4009412/how-to-use-arguments-from-prepret-command

एक बोनस के रूप में यह न केवल बैश में बल्कि सभी कार्यक्रमों में काम करेगा जो कमांड लाइन इनपुट के प्रसंस्करण के लिए libreadline का उपयोग करता है।


2
आप एक साथ इस गठजोड़ कर सकते हैं अंकों तर्क , जैसे दूसरा तर्क पकड़ पाने के लिए Altऔर प्रेस 2.(या Esc, 2, Esc, .), अंतिम तर्क प्रेस से पीछे नहीं प्राप्त करने के लिए Alt+ -, प्रकार 2और प्रेस Alt+ .(या Esc, -2, Esc, .)।
मिठाई

@ डर्टर्ट यदि मैं चलाऊं तो एक से अधिक दलीलें चाहिए? जैसे मैं दौड़ता हूं echo 1 2 3 4तो मैं चाहता हूं 2और 3अगले आदेश के लिए
wjandrea

@ डेज़र्ट ने इसे खुद पाया! आपको बस उनके बीच एक स्पेस की तरह कुछ और टाइप करना होगा। उन्हें समाप्‍त करने के लिए, सबसे आसान तरीका है कि एक स्पेस टाइप करें फिर बैकस्पेस।
वंदारेड

1
@wjandrea होल्ड Altऔर टाइप करें 2., स्पेसबार दबाए रखें, होल्ड करें Altऔर टाइप करें 3.- यदि आप एक रेंज चाहते हैं, तो इतिहास विस्तार का उपयोग करें !!:2-3:।
मिठाई

9

जहाँ तक डिफ़ॉल्ट इंटरैक्टिव शेल bashऔर स्क्रिप्टिंग शेल dashजाता है, आप अंतिम कमांड के अंतिम तर्क$_ को वापस बुलाने के लिए उपयोग कर सकते हैं ।

$ echo "Hello World"; echo same "$_"
Hello World
same Hello World

csh और tcsh, इतिहास संदर्भ हो विशेष रूप से आदेश के अंतिम शब्द के लिए, आप उपयोग कर सकते हैं !$, और व्यक्तिगत तर्क के लिए - !:<index>:

~% echo foo bar
foo bar
~% echo !$
echo bar
bar

% echo bar baz
bar baz
% echo !:1
echo bar
bar

सामान्य तौर पर, objectAएक चर के लिए जो कुछ भी है उसे असाइन करना बेहतर है , और इसे कई कमांड, लूप, आदि में उपयोग करें। वैकल्पिक रूप से, एक फ़ंक्शन एक विकल्प हो सकता है:

$ foo(){ echo "$@"; stat --print="%F\n" "$@";}
$ foo testdir
testdir
directory

1
मैं केवल यह बताना चाहूंगा कि इतिहास में कमांड को सहेजने से पहले बाद की $_तुलना !#:nमें थोड़ा अलग तरीके से काम किया जाता है। इसलिए इतिहास में वापस जाना अभी भी कमांड को दिखाएगा $_जबकि !#:nइसकी वास्तविक कीमत के साथ प्रतिस्थापित किया गया होगा। दोनों की अपनी अच्छाईयाँ और बुराईयाँ हैं।
दान

3
इसके अलावा, हमेशा की तरह, $_उद्धृत किया जाना चाहिए, अन्यथा यह सब कुछ की तरह विभाजित और ग्लोब हो जाता है। (हम अभी इसे यहाँ नहीं देखते हैं क्योंकि यह echoएक ही स्थान के साथ इसके तर्कों में शामिल होता है।) लेकिन जैसे touch "hello there"; ls -l $_ काम नहीं करेगा।
इलकाचू

1
@ मुझे लगता है कि सबसे बड़ा समर्थक $_यह है कि यह पोर्टेबल है। आखिर, !#:nबैश-विशिष्ट है।
सर्गी कोलोडियाज़नी

3

मैं स्टीलड्राइवर के उत्तर में दिए गए इतिहास के दृष्टिकोण के खिलाफ सुझाव दूंगा । यह वैश्विक स्थिति पर निर्भर करता है, जो हमेशा भंगुर होता है।

बेहतर सभी उचित आदेशों का उपयोग करते हुए लूप को ऊपर करना है, एक उचित चर का उपयोग करके:

$ for c in touch gedit; do $c foo.txt; done

सामान्य तौर पर थोड़ी सी समस्या यह है कि जब कोई विफलता होती है तो बैश गर्भपात नहीं करता है, अर्थात यह वास्तव में touch foo.txt; gedit foo.txtइसके साथ व्यवहार करने के बजाय व्यवहार करता है &&। तो, सुरक्षित होने के लिए आप एक जोड़ सकते हैं break:

$ for c in touch gedit; do $c foo.txt || break; done

1

एक-लाइनर को पकाते समय, मैं कभी-कभी अपनी दोहराई गई चीज़ को शेल वेरिएबल में असाइन करता हूं जो मैं कमांड में कई बार उपयोग करता हूं। मैं कर्सर को पास लाने के लिए अप-एरो, कंट्रोल + ए, कंट्रोल + राइट-एरो के साथ एक अलग आर्ग का उपयोग करने के लिए इसे याद और संपादित कर सकता हूं t=

t=testloop; asm-link -d "$t.asm" && perf stat -r2 ./"$t"

ध्यान दें कि इससे एक्सटेंशन पर, या नाम पर भिन्नता से निपटने में आसानी होती है।

यह भी ध्यान दें कि मुझे ;चर असाइनमेंट के बाद की आवश्यकता है , क्योंकि var=value cmdबस उस कमांड के लिए एक पर्यावरण चर के रूप में सेट करता है, और शेल संदर्भ को प्रभावित नहीं करता है।

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