बैश में एक उद्धृत स्ट्रिंग के अंदर एक पर्यावरण चर का उपयोग कैसे करें


91

मैंने बैश स्क्रिप्ट में निम्नलिखित विभिन्न रूपों की कोशिश की है:

#!/bin/bash
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

लेकिन मुझे COLUMNSपर्यावरण चर का सही ढंग से विस्तार करने के लिए वाक्यविन्यास नहीं मिल सकता है ।

मैंने निम्नलिखित विभिन्न रूपों की कोशिश की है:

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W $COLUMNS'

तथा

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W ${COLUMNS}'

तथा

eval svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

सुझाव?


तो उन उदाहरणों का आपके मामले में क्या असर होता है? और आप उन्हें क्या उत्पादन करना चाहते हैं?

स्क्रिप्ट के बाहर कमांड काम कर रहा है?
dfa

क्या आपने कोशिश की हैsvn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W ""$COLUMNS"
कियान चेन

बीटीडब्लू का उपयोग करते हुए, $@इसे बिल्कुल वैसा ही बना देता है $*- जो यह कहना है कि यह "foo bar"दो अलग-अलग तर्कों में टूट जाता है, fooऔर bar। यदि आप मूल तर्क सूची को संरक्षित करना चाहते हैं जैसा कि आपको दिया गया था, आप चाहते हैं "$@"
चार्ल्स डफी ने

जवाबों:


16

यदि अनिश्चित है, तो आप टर्मिनल पर 'cols' अनुरोध का उपयोग कर सकते हैं, और COLUMNS को भूल सकते हैं:

COLS=$(tput cols)

जो भी कारण के लिए, यह एकमात्र समाधान है जो मैं इस पृष्ठ पर काम करने में सक्षम था (11 / मई 10:38 ईटी के रूप में)। साभार
जेमी

397

Google के माध्यम से यहां आने वाले किसी भी व्यक्ति के लिए बस एक त्वरित नोट / सारांश शीर्षक में पूछे गए सामान्य प्रश्न के उत्तर की तलाश में है (जैसा कि मैं था)। निम्नलिखित में से कोई भी उद्धरण के अंदर शेल चर तक पहुंच प्राप्त करने के लिए काम करना चाहिए:

echo "$VARIABLE"
echo "${VARIABLE}"

एकल उद्धरणों का उपयोग मुख्य मुद्दा है। बैश संदर्भ मैनुअल के अनुसार :

एकल उद्धरण में वर्ण संलग्न करना ( ') उद्धरणों के भीतर प्रत्येक वर्ण के शाब्दिक मूल्य को संरक्षित करता है। एकल उद्धरण के बीच एक एकल उद्धरण नहीं हो सकता है, तब भी जब एक बैकस्लैश द्वारा पूर्ववर्ती हो। [...] दोहरे उद्धरण चिह्नों में संलग्न वर्ण ( ") के अपवाद के साथ उद्धरण के भीतर सभी पात्रों का शाब्दिक मूल्य को बरकरार रखता है, $, `, \, और, जब इतिहास विस्तार सक्षम किया गया है, !। अक्षर $और `दोहरे उद्धरणों के भीतर अपने विशेष अर्थ को बनाए रखते हैं (शैल विस्तार देखें)। जब निम्न पात्रों में से एक के बाद बैकस्लैश केवल अपने विशेष अर्थ को बरकरार रखे हुए: $, `, ",\, या न्यूलाइन। दोहरे उद्धरण चिह्नों के भीतर, इन वर्णों में से एक के बाद आने वाले बैकस्लैश हटा दिए जाते हैं। एक विशेष अर्थ के बिना वर्णों के पूर्ववर्ती बैकस्लैम को अनमॉडिफाइड छोड़ दिया जाता है। एक दोहरे उद्धरण को दोहरे उद्धरण के भीतर उद्धृत किया जा सकता है, इसे एक बैकस्लैश के साथ पूर्ववर्ती करके। यदि सक्षम है, तो इतिहास विस्तार तब तक किया जाएगा जब तक कि !दोहरे उद्धरण चिह्नों में एक बैकस्लैश का उपयोग करके भाग न जाए। बैकस्लैश पूर्ववर्ती को !हटाया नहीं गया है। विशेष पैरामीटर *और @विशेष अर्थ है जब दोहरे उद्धरण में (शेल पैरामीटर विस्तार देखें)।

प्रश्न में पूछे गए विशिष्ट मामले में, $ COLUMNS एक विशेष चर है, जिसमें अमानक गुण होते हैं (ऊपर lunath का उत्तर देखें)।


20
एकल उद्धरण के मामले में, शायद यह वर्कअराउंड मदद करता है: 'before'"$variable"'after'(जैसा कि इस उत्तर में बताया गया है: stackoverflow.com/a/13802438/2254346 )
MakisH

बहुत बढ़िया जवाब! मैं एक ही उद्धरण के भीतर अपने एनवी चर का उल्लेख करने का एक ही मुद्दा था। एक बार जब मैंने अपने एकल उद्धरण को दोहरे उद्धरण चिह्नों में बदल दिया, तो मेरे env वैरिएबल को विस्तार दिया जा रहा था।
बिनीता भारती

14

ध्यान दें COLUMNS:

  1. नहीं एक वातावरण चर। यह एक साधारण बैश पैरामीटर है जो बैश द्वारा ही सेट किया जाता है।
  2. SIGWINCHसिग्नल मिलने पर स्वचालित रूप से सेट करें ।

उस दूसरे बिंदु का आमतौर पर मतलब है कि आपका COLUMNSचर केवल आपके इंटरेक्टिव शेल में सेट किया जाएगा , कि किसी बैश स्क्रिप्ट में।

यदि आपकी स्क्रिप्ट stdinआपके टर्मिनल से जुड़ी है, तो आप अपने टर्मिनल से मैन्युअल रूप से अपने टर्मिनल की चौड़ाई पूछ सकते हैं:

tput cols

और अपने SVN कमांड में इसका उपयोग करने के लिए:

svn diff "$@" --diff-cmd /usr/bin/diff -x "-y -w -p -W $(tput cols)"

(नोट: आपको उद्धृत करना चाहिए "$@"और eval;-) से दूर रहना चाहिए )


जानकारी के लिए धन्यवाद; व्हाट्सएप पर जाने से इस मुद्दे पर मतभेद पैदा होता है।
जॅमी

2

निम्नलिखित स्क्रिप्ट कई मूल्यों के लिए मेरे लिए काम करती है $COLUMNS। मुझे आश्चर्य है कि क्या आप COLUMNSइस कॉल से पहले सेटिंग नहीं कर रहे हैं ?

#!/bin/bash
COLUMNS=30
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

क्या आप $COLUMNSअपनी स्क्रिप्ट के अंदर यह देखने के लिए प्रतिध्वनित कर सकते हैं कि क्या वह सही तरीके से सेट है?


बू, उसका पुन: निर्विवाद $@- जो एक एकल पैरामीटर "two words"को दो अलग-अलग मापदंडों में विभाजित करता है, twoऔर words"$@"तर्क सूची को पास करना चाहिए जैसा कि दिया गया था।
चार्ल्स डफी ने

0

आप इसे सही कर रहे हैं, इसलिए मुझे लगता है कि कुछ और गलती है (निर्यात-इंगम नहीं?)।

इन मामलों को डीबग करने का एक ट्रिक है एक विशेष कमांड (प्रोग्रामिंग भाषा के लोगों के लिए एक बंद) बनाने के लिए। एक कॉलम स्क्रिप्ट बनाएं, जिसका नाम है-कॉलम करना:

exec /usr/bin/diff -x -y -w -p -W "$COLUMNS" "$@"

और बस उपयोग करें

svn diff "$@" --diff-cmd  diff-columns

इस तरह से आपका कोड पढ़ने और अधिक मॉड्यूलर (टॉप-डाउन दृष्टिकोण) के लिए क्लीनर है, और आप अलग-अलग कॉलम कोड का अलग-अलग (नीचे-ऊपर का दृष्टिकोण) परीक्षण कर सकते हैं।


प्रक्रिया के कांटेक्ट होने से पहले कमांडलाइन को पार्स कर दिया जाता है, इसलिए COLUMNS को निर्यात नहीं करना समस्या नहीं हो सकती है।
पीटर वैन डेर हाइजेन

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