2010-08-10 21 views
8
C:\>type c:\output.txt 
abcd 
C:\>type c:\output.txt | set /p V1= 

C:\>set 
... A bunch of junk, NOT seeing "V1" 

क्या हुआ? SET के लिए सभी दस्तावेज के अनुसार मैंने देखा है,% V1% को ऊपर से "abcd" का मान असाइन किया जाना चाहिए था, नहीं?पाइप के बाद "सेट-पी" क्यों काम नहीं करता है?

यदि यह मायने रखता है तो मैं विंडोज एक्सपी प्रो, एसपी 3 पर हूं।

उत्तर

11

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

+0

संयोग से, मुझे एक कार्यक्रम के स्टडआउट से एक संख्या लेने की आवश्यकता है, उस पर कुछ गणित करें, और फिर इसे दूसरे पर पाइप करें उपयोग के लिए। ऐसा लगता है कि यह चाल है: गूंज 5 | (सेट/पी TmpVar = && सेट/एक TmpVar/2)> सी: \ test.txt – TonyM

+1

+1; दरअसल समस्या यह है कि विंडोज़ कैसे पाइप लागू करता है। देखें [कोड के एक पाइप ब्लॉक के अंदर देरी विस्तार क्यों विफल रहता है?] (Http://stackoverflow.com/q/8192318/1012053) तंत्र के पूर्ण स्पष्टीकरण के लिए, कई रोचक साइड इफेक्ट्स के साथ। – dbenham

3

क्या doco आपset आदेश के लिए देखा है लेकिन set /? के उत्पादन में स्पष्ट रूप से मैं नहीं जानता:

/पी स्विच आप एक के लिए एक चर के मूल्य निर्धारित करने की अनुमति देता है इनपुट की लाइन उपयोगकर्ता द्वारा दर्ज की गई।

(मेरा इटालिक्स)। मुझे लगता है कि मानक इनपुट के माध्यम से पाइप करने की कोशिश कर रहे हैं, इस पर ध्यान दिए बिना set /p कंसोल से अपना इनपुट प्राप्त कर रहा है। यह इंतजार क्यों नहीं कर रहा है, मुझे यकीन नहीं है। echo xxx | set /p xx= भी चर सेट करने में विफल रहता है।

लेकिन, आप एक ही पंक्ति फ़ाइल से एक चर सेट करना चाहते हैं, तो आप सिर्फ इनमें से किसी एक का उपयोग कर सकते हैं: दूसरा एक सरल है

for /f "delims=" %%i in (c:\output.txt) do set V1=%%i 
set /p V1=<c:\output.txt 

कि लेकिन यह बहुत मदद नहीं करता है अगर आप चाहते हैं एक मनमानी कमांड के आउटपुट को पकड़ने के लिए, लेकिन आपको इसे पहले फ़ाइल में निर्देशित करना पड़ सकता है।

for /f "delims=" %%i in ('echo AAA') do set xx=%%i 

वहाँ जिससे पता चलता है कि यह संदर्भों के साथ क्या करना है this page पर एक दिलचस्प टुकड़ा है::

पहले एक तुम्हारे बिना अस्थायी फ़ाइलों को मनमाना आदेशों निष्पादित करने के लिए अनुमति देता है

ठीक है, मैंने खुद को क्यों पाया। ऐसा इसलिए है क्योंकि | एक नया संदर्भ बनाता है ताकि चर कभी भी वर्तमान संदर्भ के बाकी हिस्सों तक नहीं पहुंच सके। सबूत:
> set bar=

bar=aaa
> set bar
Environment variable bar not defined

हालांकि मुझे लगता है कि इस निष्कर्ष की सच्चाई पर टिप्पणी करने से मनाही है। मुझे नहीं पता कि इस संदर्भ में कौन से संदर्भ हैं, मैं इसे पूर्णता के लिए आपके ध्यान में ला रहा हूं।

+0

क्षमा करें, मैंने 10 से अधिक वर्षों में कोई बैच कोडिंग नहीं किया है और इस प्रकार मेरा सिर यूनिक्स विचारों द्वारा प्रदूषित है कि एसटीडीआईएन एसटीडीआईएन है ...मुझे लगता है कि आप सही हैं कि "उपयोगकर्ता द्वारा" डिफ़ॉल्ट रूप से डॉस-दुनिया में "एसटीडीआईएन" का पर्याय नहीं है (हां, मुझे कुछ यूनिक्स प्रोग्राम खींचने के लिए डरावनी टीटीवी पहचान सामग्री के बारे में पता है, लेकिन अपवाद प्राप्त करने के लिए यह दुर्लभ और कठिन है :) मुझे इन संदर्भों के बारे में और अधिक पढ़ने की आवश्यकता होगी (वास्तव में कल रात उस पृष्ठ को देखा गया था, लेकिन इसे पूरी तरह से पार्स करने के लिए बहुत थक गया था। – DVK

+1

ठीक है, मुझे लगता है कि आप वास्तव में सही हैं, @ डीवीके, उपर्युक्त उत्तर में मेरे मूल पैराग्राफ के बावजूद। यह स्पष्ट रूप से है _some_ एसटीडीआईएन का प्रकार 'सेट/पी वी 1 = <सी: \ output.txt' ठीक काम करता है। यह केवल पाइप किस्म है जो काम नहीं कर रहा है। – paxdiablo

+1

समस्या एसईटी कमांड और सबकुछ करने के लिए कुछ भी नहीं है विंडोज़ कैसे पाइप लागू करता है। टोनीएम का जवाब देखें, साथ ही लिंक जो मैंने एक टिप्पणी में रखा है। – dbenham

1

इस मूल प्रश्न है, जो Why doesn't [..] work? पूछा के लिए एक सीधा जवाब नहीं है, लेकिन इस सवाल का जवाब एक ̲ ग ̲ ज करने के लिए देख लोगों के लिए उपयोगी हो सकता है ̲ मैं ̲ ई ̲ वी ̲ ई ̲ क्या तार्किक परिणाम होगा कुछ इस तरह की:

echo:somevalue|set /p somevar= 

सामान्य वैकल्पिक हल, ऊपर कोड के लिए उदाहरण के लिए, होगा:

echo:somevalue>tempfile.txt&set /p somevar=<tempfile.txt 

जो काम पूरी तरह से करता है, सिवाय इसके कि यह एक नई फाइल बनाता है जिसे बाद में निपटाया जाना चाहिए (इस तथ्य के शीर्ष पर कि यह सुनिश्चित करने के लिए हमें अतिरिक्त कदम उठाने की आवश्यकता है कि यह नई फ़ाइल किसी मौजूदा व्यक्ति को ओवरराइट नहीं करेगी हमने प्रतिस्थापित नहीं किया या कभी भी इरादा नहीं बनाया)।

हालांकि यह सच है वहाँ कोई रास्ता नहीं पाइप | ऑपरेटर जहाँ तक वातावरण चर का संबंध है के दोनों किनारों भर की खाई को पाटने के लिए एक फ़ाइल धारा का उपयोग कर चारों ओर, एक Windows NT वातावरण तहत किया जा रहा है, और प्रदान की illustrating एक उनका उपयोग कैसे हो सकता है सही एक उदाहरण में alternate data streams

आइए कूद:

echo:somevalue>".\%~nx0":temp&set /p somevar=<".\%~nx0":temp 
मात्रा स्क्रिप्ट NTFS फ़ाइल सिस्टम उपयोग कर रहा है पर रहता है, एक कुछ अस्थायी फ़ाइलों की तुलना में कहीं अधिक सुरुचिपूर्ण उपयोग कर सकते हैं

यहां %~nx0 खड़ा है, और इसमें फ़ाइल नाम (आधार नाम + एक्सटेंशन) हमारी बैच फ़ाइल का विस्तार किया गया है, जिसमें रिक्त स्थान होने पर उद्धरणों में संलग्न है।

नोट: एक के बजाय %0 सीधे (उद्धरण के बिना) इस्तेमाल कर सकते हैं जबकि को वर्तमान स्क्रिप्ट उल्लेख करने के लिए, .\%~nx0 अगर आप कभी भी, जबकि डिबगिंग आदेश का विस्तार मूल्य पर देखने की जरूरत अधिक प्रबंधनीय है आपकी स्क्रिप्ट, विशेष रूप से यदि आपकी स्क्रिप्ट का पूरा पथ काफी लंबा है।

जैसे, ".\%~nx0":temp एक वैकल्पिक डेटा स्ट्रीम (एडीएस) हमारे खुदtemp नामित स्क्रिप्ट के के लिए, उदाहरण के लिए myscript.cmd:temp संदर्भित करता है, कि हम बनाने के (या ऊपर लिख) echo आदेश के उत्पादन के साथ। चूंकि एडीएस एक फ़ाइल की डिफ़ॉल्ट स्ट्रीम के समान व्यवहार करता है, echo और set आदेशों में कोई अंतर नहीं दिखता है।

एक पूरी स्क्रिप्ट विधि का उपयोग कर ऐसा दिखाई दे सकता:

@echo off 
set __self=".\%~nx0" 
set __adsname=test.dat 

:: Using some input... 
set [email protected],-23000 
echo:Input: %l_input% 
echo: 

:: ...we process it... 
expand_str_res_id.exe %l_input%>%__self%:%__adsname%&set /p l_output=< %__self%:%__adsname% 

:: ...and show the output, e.g. "File and Printer Sharing" 
echo:Output: %l_output% 
echo: 

:cleanup 
set l_input= 
set l_output= 
type nul> %__self%:%__adsname% 
set __self= 
set __adsname= 
pause 

यहाँ, स्क्रिप्ट, लाइन type nul> %__self%:%__adsname, जो type nul> ".\myscript.cmd":test.dat की तरह कुछ करने के लिए विस्तारित किया जा सकता है के अंत में, सामग्री स्पष्ट करने के लिए प्रयोग किया जाता है वैकल्पिक डेटा स्ट्रीम का हमने अभी उपयोग किया है। यद्यपि यह वैकल्पिक डेटा स्ट्रीम का आकार शून्य पर सेट करता है, यह मिटा देता है (नीचे नोट देखें)।

कुछ अंतिम नोट्स:

  1. अधिकांश आदेशों को नहीं समझ सकता या वैकल्पिक डेटा के साथ काम धाराओं जब वे स्रोत फ़ाइलों के रूप में प्रदान की जाती हैं। इसका मतलब है कि निम्नलिखित का उपयोग नहीं किया जा सकता है:

    • type, उदा।
    • copy, उदा। copy myscript.cmd:data myscript_data.txt
    • move, उदा। move myscript.cmd:data myscript_data.txt
    • del/erase, उदा। del myscript.cmd:data
    • ren/rename, उदा। start आदेश: ren myscript.cmd:data myscript.cmd:data.txt
    • और इतने

    वास्तव में, यह वास्तव में केवल फ़ाइल पुनर्निर्देशन कि एक अपवाद (मैं के बारे में सोच सकते हैं कि) के साथ धाराओं वैकल्पिक डेटा का समर्थन करता है है।

  2. हालांकि हम कर सकते हैं काफी आसानी से स्पष्ट/एक वैकल्पिक डेटा स्ट्रीम की सामग्री, को हटाने एक पर फ़ाइल कॉपी या नाम बदलने यह किसी भी स्ट्रीम (अच्छी तरह से :$DATA वाले) को शामिल नहीं करता क्योंकि काफी जटिल काम है, और संपादन मिटा/बदल रहा है फ़ाइल की सामग्री केवल डिफ़ॉल्ट डेटा स्ट्रीम को प्रभावित करती है। फिर भी, हम हम क्या हासिल करने की कोशिश कर रहे हैं पर निर्भर करता है कुछ ही विकल्प हैं:
    • हम केवल एक ही वैकल्पिक डेटा स्ट्रीम है, तो या एक ही बार में उन सभी को को हटाने कोई आपत्ति नहीं है, और सामग्री फ़ाइल का केवल पाठ है, फिर हम को केवल को निम्न फ़ाइल type myscript.cmd > myscript_clean.cmd का उपयोग करके मूल फ़ाइल की डिफ़ॉल्ट डेटा स्ट्रीम रखकर एक नई फ़ाइल बना सकते हैं, जिसके बाद मूल फ़ाइल हटा दी जा सकती है।
    • हम मात्रा और Windows Vista या ओएस के बाद के संस्करण के तहत काम पर प्रशासनिक अधिकार है, तो हम एक वैकल्पिक डेटा स्ट्रीम के लिए एक प्रतीकात्मक लिंक बनाने के लिए है, जो तब एक के साथ हमें प्रदान करेगा MKLINK उपयोग कर सकते हैं सामान्य फ़ाइल प्रबंधन आदेशों के साथ मानक फ़ाइल नाम का उपयोग किया जाना चाहिए।
    • वैकल्पिक रूप से, Streams, LADS, या AlternateStreamView जैसे वैकल्पिक डेटा स्ट्रीम में हेरफेर करने के लिए उपलब्ध कई टूल में से एक का उपयोग कर सकते हैं।
  3. एक उपयोगी आदेश नियमित फ़ाइलों सूची कमांड लाइन से वैकल्पिक डेटा स्ट्रीम dir /a-d /r है भी शामिल है। फिर आप फ़ाइल के नाम (वैकल्पिक) डेटा स्ट्रीम तक पहुंचने के लिए किसी भी प्रोग्राम का उपयोग कर सकते हैं, उदा। notepad.exe myscript.cmd:data

मुझे आशा है कि इससे मदद मिलती है!

संबंधित मुद्दे