`स्रोत` कमांड के विपरीत


9

मैं sourceचर मूल्यों को पढ़ने / प्रिंट करने के लिए अपनी बैश स्क्रिप्ट में कमांड का उपयोग करता हूं

more linuxmachines_mount_point.txt

export linuxmachine01="sdb sdc sdf sdd sde sdg"
export linuxmachine02="sde sdd sdb sdf sdc"
export linuxmachine03="sdb sdd sdc sde sdf"
export linuxmachine06="sdb sde sdf sdd"

source  linuxmachines_mount_point.txt

echo $linuxmachine01
sdb sdc sdf sdd sde sdg

sourceचरों को परेशान करने के लिए इसके विपरीत क्या है ?

अपेक्षित परिणाम

echo $linuxmachine01

< no output >

14
ऐसा नहीं है sourceकि आपके वातावरण में चर सेट कर रहे हैं, लेकिन exportफाइल में स्टेटमेंट्स जो आप source। तो इसके विपरीत sourceहो सकता है source, अगर आप sourceएक अलग फ़ाइल जो unsetसभी एक ही चर है।
user4556274

2
येल, निर्यात का उपयोग न करें, बस नाम = "वैल" का उपयोग करें। निर्यात स्क्रिप्ट-से-बायनेरी चर (पर्यावरण) के लिए है।
ctrl-d


2
यह असंभव है। आप जिस अवधारणा की तलाश कर रहे हैं, उसे प्रतिवर्ती कम्प्यूटिंग कहा जाता है । प्रतिवर्ती होने के लिए प्रोग्रामिंग भाषाओं को विशेष रूप से कुछ गंभीर प्रतिबंधों के साथ डिज़ाइन करने की आवश्यकता है। बैश उन प्रोग्रामिंग भाषाओं में से एक नहीं है।
जोर्ग डब्ल्यू मित्तग

1
@ येल, यह असत्य है (और आप स्पष्ट रूप से परीक्षण को कभी नहीं चलाते हैं जिसे आप ctrl-d करना चाहते हैं); आपको पूरी तरह से exportएस की जरूरत नहीं है । सभी exportपर्यावरण में मूल्यों की नकल करते हैं - लेकिन वे शेल चर के रूप में मौजूद हैं या नहीं, वे पर्यावरण चर के रूप में भी परिभाषित हैं या नहीं। इसके अलावा, अनावश्यक वातावरण चर को परिभाषित करने से आपकी अधिकतम कमांड लाइन की लंबाई कम हो जाती है, क्योंकि वे एक ही (सीमित!) प्रति-प्रक्रिया स्थान में संग्रहीत होते हैं।
चार्ल्स डफी

जवाबों:


21

उपधारा का उपयोग करना (अनुशंसित)

स्रोत कमांड को सब-टाइम में चलाएँ:

(
source linuxmachines_mount_point.txt
cmd1 $linuxmachine02
other_commands_using_variables
etc
)
echo $linuxmachine01  # Will return nothing

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

अनसेट का उपयोग करना

यह किसी भी चर का निर्यात करता है linuxmachines_mount_point.txt:

unset $(awk -F'[ =]+' '/^export/{print $2}' linuxmachines_mount_point.txt)
  • -F'[ =]+' क्षेत्र विभाजक के रूप में रिक्त स्थान और समान संकेतों के किसी भी संयोजन का उपयोग करने के लिए अजीब बताता है।

  • /^export/{print $2}

    यह awk को उन लाइनों का चयन करने के लिए कहता है जो इसके साथ शुरू होती हैं exportऔर फिर दूसरे फ़ील्ड को प्रिंट करती हैं।

  • unset $(...)

    यह कमांड को अंदर चलाता है $(...), इसके स्टडआउट को पकड़ता है, और इसके आउटपुट द्वारा नामित किसी भी चर को अनसेट करता है।


इसका उपयोग क्यों नहीं करना है - i in `awk '{$ $ 2}' फ़ाइल में | awk -F "=" '{प्रिंट $ 1}' '; $ unset करो; किया हुआ ? (
शुरुआत के

2
@ येल एक अतिरिक्त प्रक्रिया और एक लूप का उपयोग करता है जब न तो आवश्यकता होती है। मत भिन्न हो सकते हैं लेकिन मुझे यह उतना सरल नहीं लगता। इसके अलावा और संभावित रूप से खतरनाक, यह मानता है कि हर पंक्ति fileएक निर्यात विवरण है।
जॉन 1024 20

8
@yael इसके अलावा, चर को अनसुना करना और अन्य कोड साइड-इफ़ेक्ट्स को पूर्ववत करना बिल्कुल वही है जो उप-संस्करण हैं। वे इसे बस और मज़बूती से करते हैं। जब तक कि कुछ विशेष कारण नहीं है, तब तक, उपधाराएं वही हैं जो आपको उपयोग करनी चाहिए।
जॉन 1024

4

आप sourceस्क्रिप्ट नहीं खोल सकते ।

आप एक अस्थायी फ़ाइल में सभी निर्यात किए गए चर को संग्रहीत करने के लिए क्या कर सकते हैं, स्क्रिप्ट के सॉर्ट होने के बाद चर के साथ तुलना करें, और फिर इसके साथ अतिप्रवाह हटा दिया जाता है unset, जैसे:

export > temp_file
source myscript

#... do some stuff

unset "$(comm -3 <(sort temp_file) <(export | sort) | awk -F'[ =]' '{print $3}' | tr '\n' ' ')"

इसका उपयोग क्यों नहीं करना है - i in `awk '{$ $ 2}' फ़ाइल में | awk -F "=" '{प्रिंट $ 1}' '; $ unset करो; किया हुआ ? (
शुरुआत के

@ यह केवल तभी काम करेगा जब स्क्रिप्ट में केवल exportएस होता है।
जिमीज

आप "निर्यात s" का क्या मतलब है, मेरी फाइल में linuxmachine01 = "sdb sdc sdf sdd sde sd sdg" इत्यादि शामिल हैं, और जब मैं awk लूप को बिना किसी समस्या के परिवर्तनशील चर का उपयोग करता हूं
ya 20

@ येल मुझे नहीं पता कि आपकी फ़ाइल कैसी दिखती है, इसलिए मैंने कुछ सामान्य उत्तर दिए, उदाहरण के लिए यदि स्क्रिप्ट में शीर्ष पर एक टिप्पणी है "# यहां माउंट पॉइंट्स के साथ निर्यात करने के लिए कुछ चर हैं।"
जिमीज

2

आप unsetचर को "भूल" करने के लिए कमांड का उपयोग कर सकते हैं ।


फ़ाइल अलग-अलग मशीनों के साथ हो सकती है, इसलिए फ़ाइल में दूसरे चर को कैसे अनसेट करें?
येल

unset varablename इसे भूल जाएंगे (आप इसे bash / sh / ksh / zsh man पेज में समझा सकते हैं) इसका डेमो: pastebin.com/MGQyTZEA
francois P

हां, लेकिन क्योंकि चर भिन्न हो सकते हैं, बैश स्क्रिप्ट को फ़ाइल से चर को पढ़कर उन्हें करना होगा और उन्हें परेशान करना होगा, यह स्थिर नहीं हो सकता है क्योंकि चर अज्ञात है
येल

तो ग्रेप तुम्हारा फ़ाइल से सूची चर लाइनों (कट) निर्यात को सेट किए बिना निर्यात linuxmachine06 होने के लिए = "SDB SDE एसडीएफ SDD" तो आप linuxmachine06 को सेट किए बिना उदाहरण के लिए एक नाम के रूप में मिलती है: pastebin.com/M9eCtLc7 के रूप में आप को सेट किए बिना आदेश यहाँ doen देखना 'चर नाम पता है कि यह केवल अंत में जाना जाता है
फ्रेंकोइस पी

ठीक है मैं इस सिंटैक्स का उपयोग करने के लिए परेशान करूंगा - क्योंकि मैं `awk '{प्रिंट $ 2}' फ़ाइल में हूँ awk -F "=" '{प्रिंट $ 1}' '; $ unset करो; किया
येल

2

आपके द्वारा अपेक्षित उत्पादन (कुछ भी नहीं) के लिए सबसे सरल समाधान चर को फिर से खाली घोषित करना है:

$ export linuxmachine01="sdb sdc sdf sdd sde sdg"
$ echo "$linuxmachine01"
sdb sdc sdf sdd sde sdg

$ linuxmachine01=""
$ echo "$linuxmachine01"
$

बेशक चर अभी भी परिभाषित है (और निर्यात), खाली लेकिन परिभाषित:

$ declare -p linuxmachine01
declare -x linuxmachine01=""

पर्यावरण और रनिंग शेल दोनों से चर को सही ढंग से हटाने के लिए आपको अनसेट (अनुशंसित तरीका) का उपयोग करना चाहिए:

$ unset linuxmachine01
$ declare -p linuxmachine01
bash: declare: linuxmachine01: not found
$ echo "$linuxmachine01"
$

1

ऐसा करने का सबसे सरल तरीका आपकी स्क्रिप्ट को संशोधित करना है, ताकि यह स्क्रिप्ट के प्रभाव को पूर्ववत करने के लिए एक कमांड को परिभाषित करे:

export linuxmachine01="sdb sdc sdf sdd sde sdg"
export linuxmachine02="sde sdd sdb sdf sdc"
export linuxmachine03="sdb sdd sdc sde sdf"
export linuxmachine06="sdb sde sdf sdd"
alias linuxmachines_mount_point='for v in linuxmachine01 linuxmachine02 linuxmachine03 linuxmachine04; do unset $v; done; unalias linuxmachines_mount_point'

एक फ़ंक्शन के बजाय एक उपनाम क्यों? ध्यान दें कि उपनाम डिफ़ॉल्ट रूप से गैर-सक्रिय शेल में अक्षम हैं, इसलिए आउट-ऑफ-द-बॉक्स, यह एक स्क्रिप्ट में काम नहीं करेगा।
चार्ल्स डफी

... वास्तव में, यह और भी आसान होगा यदि हम सिर्फ एक चर को परिभाषित करते हैं , और इस प्रकार केवल एक को ही परेशान करना declare -A linuxmachines=( [01]="sdb sdc sdf" [02]="sde sdd sdb" [03]="whatever" )पड़ता है : तो यह सिर्फ unset linuxmachinesवापस करना है।
चार्ल्स डफी

@CharlesDuffy: इस उद्देश्य के लिए उपनाम और फ़ंक्शन दोनों ठीक हैं। इसका कारण यह है कि मैं एक चर में सब कुछ डालने का सुझाव नहीं देता हूं, यह पूर्ववत आदेश को परिभाषित करना अधिक सामान्य है। आप न केवल चर बल्कि कार्यों, उपनामों, सिस्टम सेटिंग्स, टर्मिनल सेटिंग्स आदि को अपरिभाषित कर सकते हैं, यह एक बेहतर अमूर्तता प्रदान करता है क्योंकि आपको पूर्ववत आदेश की सटीक सामग्री के बारे में परवाह नहीं है।
रेयान

मेरा मानना ​​है कि ऊपर मेरी बात यह है कि उपनाम उद्देश्य के लिए ठीक नहीं हैं, अगर "उद्देश्य" में गैर-सक्रिय उपयोग (यानी लिपियों से आह्वान) शामिल है।
चार्ल्स डफी

0

आप अपना linuxmachines_mount_point.txt इस तरह लिख सकते हैं

test "$linuxmachine01" && unset -v linuxmachine01 || linuxmachine01="sdb sdc sdf sdd sde sdg"

जब आपको अपने चरों की आवश्यकता होगी

source linuxmachines_mount_point.txt

जब आप चरों को हटाना चाहते हैं

source linuxmachines_mount_point.txt

0

यदि आप sourceकमांड को सक्रिय करने के लिए उपयोग कर रहे हैं VirtualEnvironment, तो आप कमांड का उपयोग करके इसे बाहर निकाल सकते हैं deactivate

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