क्या यह एक फ़ाइल को दूसरे पर पुनर्निर्देशित करने के लिए यूयूओसी (बिल्ली का बेकार उपयोग) है?


36

अगर मैं file2मैच की सामग्री बनाना चाहता हूं file1, तो मैं जाहिर तौर पर बस चला सकता हूं cp file1 file2

हालांकि, अगर मैं सुरक्षित रखना चाहते हैं सब कुछ के बारे में file2 छोड़कर सामग्री मालिक, अनुमतियाँ, विस्तारित गुण, एसीएल, हार्ड लिंक, आदि, आदि, तो मैं नहीं चलाना चाहूंगा cp। * उस मामले में मैं बस खटखटाने से करना चाहते हैं की सामग्री file1में file2

ऐसा लगता है कि निम्नलिखित ऐसा करेंगे:

< file1 > file2

लेकिन यह काम नहीं करता है। file2कुछ भी नहीं लिखा है और नहीं लिखा है तथापि,

cat < file1 > file2

काम करता है

इसने मुझे चौंका दिया कि पहला संस्करण काम नहीं करता है।

क्या दूसरा संस्करण UUOC है? वहाँ एक आदेश को लागू करने के बिना ऐसा करने का एक तरीका है, केवल पुनर्निर्देशन का उपयोग करके?

नोट: मुझे पता है कि UUOC एक सच्चे विरोधी पैटर्न की तुलना में एक पांडित्यपूर्ण बिंदु है।

* जैसा कि tniles09 ने खोजा है , वास्तव में इस मामले में काम cp करेगा


3
चाहे < file1 > file2क्या आप चाहते हैं खोल पर निर्भर है नहीं करता है।
माइकल होमर

13
खैर, यह है की एक अनुपयोगी उपयोग <...
jwodder

2
एक विरोधी पैटर्न क्या है?
22

6
@jwodder - यह सच नहीं है। खासकर जब आप एक कॉपी के बारे में बात कर रहे हैं। विचार करें कि क्या होता है जब file1अस्तित्व में नहीं होता है या फिर अपठनीय होता है और आउटपुट खुलने < से पहले आप इसे >खोलते हैं, और तब विचार करते हैं कि जब आप catइसे खोलने की कोशिश करने की अनुमति देते हैं तो क्या होता है।
mikeserv

3
@JonathanLeffler अतिरिक्त catरूप से दूसरी कमांड को चलाने के लिए रिडायरेक्शंस इनवॉइस (डिफ़ॉल्ट रूप से) के साथ एक खाली कमांड zsh में । देखें स्टीफन Chazelas 'जवाब एक टिप्पणी में फिट की तुलना में है कि अधिक जानकारी के लिए नीचे दिए गए।
माइकल होमर

जवाबों:


58

cat < file1 > file2UUOC नहीं है शास्त्रीय रूप से, <और >पुनर्निर्देशन करते हैं जो सिस्टम स्तर पर डिस्क्रिप्टर डुप्लिकेट को दर्ज करने के लिए अनुरूप होता है। फ़ाइल डिस्क्रिप्टर डुप्लीकेशंस अपने आप में एक चीज़ नहीं करते हैं (ठीक है, >पुनर्निर्देशन के साथ खुलता है O_TRUNC, इसलिए सटीक होने के लिए, आउटपुट पुनर्निर्देशन आउटपुट फ़ाइल को छोटा करता है)। < >प्रतीकों को आपको भ्रमित न करें । पुनर्निर्देशन डेटा को स्थानांतरित नहीं करते हैं - वे अन्य फ़ाइल विवरणों के लिए फ़ाइल विवरणक असाइन करते हैं।

इस मामले में आप को खोलने file1और फ़ाइल वर्णनकर्ता के लिए उस फ़ाइल वर्णनकर्ता आवंटित 0( <file1== 0<file1) और file2और फ़ाइल वर्णनकर्ता के लिए उस फ़ाइल वर्णनकर्ता आवंटित 1( >file2== 1>file2)।

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


11
शायद यह सिर्फ मुझे है, लेकिन इस जवाब का मेरा पसंदीदा हिस्सा "फावड़ा" शब्द का उपयोग है। :) बहुत स्पष्ट है, धन्यवाद।
वाइल्डकार्ड

1
@Wildcard मैंने "फावड़ा" पर "पंप" को प्राथमिकता दी होगी, लेकिन फिर भी एक अच्छा शब्द। +1
मेहरदाद

फावड़ा एक अच्छा शब्द क्यों है?
बुबकज़ौबा

1
एक गंदगी का ढेर फावड़ा, एक समय में एक फावड़ा, एक ढेर से दूसरे तक डेटा को बफर से कॉपी किया जाता है। यह एक अच्छा सादृश्य है।
bsd

1
आपके पहले वाक्य में, आप कहते हैं कि फ़ाइल डिस्क्रिप्टर डुप्लिकेट किए जा रहे हैं। क्या उन्हें दोहराया या पुन: असाइन किया जा रहा है (आपके दूसरे पैराग्राफ के रूप में, और सुविधा का व्यवहार, संकेत प्रतीत होता है)?
ग्रेग बेल

17

ऐसा नहीं है, क्योंकि जैसा कि अन्य ने बताया है, प्रश्न में व्यवहार शेल-आश्रित है। जैसा कि आपने (ओपी ने) कहा है, यह थोड़ा कठिन है , शायद विनोदी भी ? , विषय की तरह।

हालांकि, जीएनयू सिस्टम पर, आपके प्रारंभिक आधार का एक और समाधान उपलब्ध है cp --no-preserve=all file1 file2:। इसे आज़माएं, मुझे लगता है कि यह आपकी वर्णित स्थिति को पूरा करेगा (जैसे file2कि इसकी विशेषताओं को संशोधित नहीं करते हुए सामग्री को संशोधित करना)।

उदाहरण :

$ ls -l
    total 8
    -rw-r--r-- 1 tniles sambashare 16 Dec 16 12:21 fezzik
    -rw-r--r-- 1 tniles tniles     14 Dec 16 12:16 fred
$ cat *
    Lookout, world!
    Hello, world!
$ cp --no-preserve=all fred fezzik 
$ ls -l
    total 8
    -rw-r--r-- 1 tniles sambashare 14 Dec 16 12:22 fezzik
    -rw-r--r-- 1 tniles tniles     14 Dec 16 12:16 fred
$ cat *
    Hello, world!
    Hello, world!

अद्यतन वास्तव में, मैंने अभी देखा कि मेरे सिस्टम के cpद्वारा ही विशेषताओं को संरक्षित करना प्रतीत होता है जब तक कि -aया -pनिर्दिष्ट न हों। मैं बैश शेल और जीएनयू कोरुटिल का उपयोग कर रहा हूं। मुझे लगता है तुम रोज कुछ नया सीखते हो...


कड़ी मेहनत और विभिन्न अनुमतियों सहित परीक्षा परिणाम (वाइल्डकार्ड द्वारा):

$ ls -li
total 12
913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1
913965 -rwxrw---- 2 pete    vagrant 39 Dec 16 20:35 file2
913965 -rwxrw---- 2 pete    vagrant 39 Dec 16 20:35 hardlinktofile2
$ cat file1
This is the contents of file1
$ cat file2
This is the original contents of file2
$ cp file1 file2
$ ls -li
total 12
913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1
913965 -rwxrw---- 2 pete    vagrant 30 Dec 16 20:37 file2
913965 -rwxrw---- 2 pete    vagrant 30 Dec 16 20:37 hardlinktofile2
$ cat file1
This is the contents of file1
$ cat file2
This is the contents of file1
$ 

अच्छा लगा। मैंने कड़ी कड़ी और अलग-अलग अनुमतियों सहित अपना स्वयं का परीक्षण चलाया और ऐसा लगता है कि आप सही हैं।
वाइल्डकार्ड

मेरे परीक्षण के परिणाम जोड़े गए; आशा है आप बुरा न मानें। :) मैंने एसीएल या विस्तारित विशेषताओं का परीक्षण नहीं किया, लेकिन यह देखते हुए कि इनोड संख्या संरक्षित है मैं 99% हूं, यकीन है कि वे भी होंगे।
वाइल्डकार्ड

अच्छा ... बुरा मत मानना। :-)
tniles

13

zshशेल में , जहां < file1 > file2काम करता है, शेल इन्वोक करता है cat

एक कमांड लाइन के लिए जिसमें केवल पुनर्निर्देशन होते हैं और न ही कोई कमांड और न ही असाइनमेंट, zshइनवोक $NULLCMD( catडिफ़ॉल्ट रूप से) जब तक कि एकमात्र रीडायरेक्शन एक <ऐसा नहीं होता है, जिसके मामले में $READNULLCMD( pagerडिफ़ॉल्ट रूप से) इसके बजाय लागू किया जाता है। (जब तक कि यह उस zshस्थिति में shया cshअनुकरण में नहीं है, जब तक कि यह उन गोले की तरह व्यवहार नहीं करता है)।

इसलिए:

< file1 > file2

वास्तव में के रूप में ही है

cat < file1 > file2

तथा

< file1

के समान है

pager < file1

रिकॉर्ड के लिए, यह वाक्यविन्यास ksh93 के लिए काम नहीं करता है
fpmurphy

8
< from > to

काम नहीं करता क्योंकि वहाँ कोई आज्ञा नहीं है; कोई प्रक्रिया नहीं। शेल फाइलों को खोलता / बनाता है और पुनर्निर्देशन की व्यवस्था करता है (जिसका अर्थ है कि इन फ़ाइलों को संदर्भित करने वाले फ़ाइल विवरणकों को 0 और 1: मानक इनपुट और मानक आउटपुट के रूप में लगाया जाता है)। लेकिन मानक इनपुट से पढ़ने और मानक आउटपुट पर लिखने के लिए लूप निष्पादित करने के लिए कुछ भी नहीं है।

zshइस "नल कमांड" मामले में एक उपयोगकर्ता-कॉन्फ़िगर करने योग्य कमांड को प्रतिस्थापित करके यह काम करता है। कमांड लाइन में कमांड दिखाई नहीं दे रहा है, लेकिन यह अभी भी है। इसके लिए एक प्रक्रिया बनाई जाती है और यह उसी तरह काम करती है। NULLCMDहै catतो, डिफ़ॉल्ट रूप से < from > toवास्तव में इसका मतलब है cat < from > to में zsh, जब तक कि NULLCMDकुछ और करने के लिए सेट है; यह एक "निहित बिल्ली" कमांड है।

एक "बिल्ली का बेकार उपयोग" तब होता है जब catएक फ़ाइल से पढ़ने के लिए मध्यस्थ के रूप में उपयोग किया जाता है और डेटा को किसी अन्य प्रक्रिया को खिलाता है, जिसका फ़ाइल विवरणक केवल मूल फ़ाइल से जुड़ा हो सकता है।

यदि catस्थिति से हटाने योग्य है, जैसे कि शेष कमांड अभी भी एक ही कार्य कर सकते हैं, तो यह बेकार है। यदि यह हटाने योग्य नहीं है, तो यह बेकार नहीं है।

# useless, removable:
$ cat archive.tar | tar tf -    #  -->  tar tf archive.tar

# not removable (in POSIX shell):
$ cat > file
abc
[Ctrl-D]

# likewise:
STRING=$(cat file)

एक catजो बदली है वह एक ही चीज नहीं है। उदाहरण के लिए, cat > fileहम vi fileफ़ाइल बनाने के लिए उपयोग कर सकते हैं । catएक ही कार्य को प्राप्त करने के लिए जो कुछ बचा है, उसका उपयोग करते हुए, इसे हटाने के रूप में गिना नहीं जाता है।

तो catहै ही निश्चित रूप से इसे निकाला नहीं जा सकता है, पाइप लाइन में आदेश तो; जो कुछ भी बचा है उसका पुनर्व्यवस्थापन समकक्ष कार्य नहीं करेगा।

कुछ शेल स्क्रिप्टर्स का उपयोग catइसलिए किया जाता है क्योंकि उन्हें लगता है कि यह उन्हें इनपुट ऑपरेटर को कमांड लाइन के बाईं ओर करीब ले जाने देता है। हालाँकि, पुनर्निर्देशन कमांड लाइन में कहीं भी हो सकते हैं:

# If you're so inclined:
# move source archive operand to the left without cat:
$ < archive.tar tar xf - > listing

btw, आपको f -टार के लिए उपयोग करने की आवश्यकता नहीं है । tar xf -बस है tar x
DNT

@mikeserv यह कहाँ कहता है कि catफ़ाइल निर्माण में शामिल है? उत्तर स्पष्ट रूप से कहता है कि शेल ऐसा करता है। आप किस समस्या का > fileजिक्र कर रहे हैं? मैं अक्सर किसी मौजूदा फ़ाइल को शून्य लंबाई तक छोटा करने या इस तरह के अस्तित्व को सुनिश्चित करने के लिए इसका उपयोग करता हूं। यह सवाल इस बारे में है कि < from > toकाम करना क्यों पसंद है cat < from > to, और UUoC, नहीं "कृपया मुझे कारण बताएं कि क्यों catएक अच्छा विकल्प नहीं है cp"।
कज़

1
@dnt, टेप आर्काइव tarहै । कई कार्यान्वयन अभी भी डिफ़ॉल्ट रूप से पहले टेप डिवाइस के साथ काम करते हैं। tar
स्टीफन चेज़लस 12

1

< file1 > file2 लगता है कि शेल-डिपेंडेंट है, zsh पर यह काम करता है, बैश पर नहीं।

संपादित करें: हटाए गए गलत कथन


cp -aकी विशेषताओं को बरकरार रखता है file1 और अधिलेखित कर देता करें 2 की विशेषताओं। इच्छित व्यवहार के विपरीत। इसके अलावा मैं मैन पेज को देखकर भी नहीं बता सकता कि हार्ड लिंक के साथ क्या होगा, लेकिन मुझे लगता है कि यह कहना सुरक्षित है कि फाइल 2 के हार्ड लिंक संरक्षित नहीं होंगे।
वाइल्डकार्ड

आप ठीक कह रहे हैं, मैंने प्रश्न को पर्याप्त सावधानी से नहीं पढ़ा।
tastytea

1

सब अच्छा जवाब के अलावा, आप से एक UUOC से बच सकते हैं अनुकरण एक cat:

awk 1 file1 > file2   # For line-oriented text, not binaries.
dd if=file1 of=file2  # Works for binary files, too.
# many more geeky ways.

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


यह सच है, लेकिन यह ध्यान देने योग्य है कि उनके पास कोई लाभ नहीं है और केवल कमियां (प्रदर्शन, विश्वसनीयता) खत्म हो गई हैं cat। यहां आपको दो फ़ाइल डिस्क्रिप्टर के बीच डेटा को शेव करने के लिए एक कमांड की आवश्यकता है और catइसके लिए सबसे अच्छे में से एक है। यह भी देखें कि pvकौन splice()लिनक्स पर पोजिशन के लिए उपयोग कर सकेगा, (हालांकि यह fadvise(POSIX_FADV_SEQUENTIAL)GNU की तरह नहीं catहै)।
स्टीफन चेज़लस

ddबाइनरी फ़ाइलों के लिए आदेश अच्छा लगता है ... या होगा catबाइनरी फ़ाइलें के लिए भी बस काम?
वाइल्डकार्ड

@Wildcard catद्विआधारी फ़ाइलों के लिए भी काम करता है (यूनिक्स आमतौर पर अलग नहीं होता है; हालांकि, कुछ उपकरण विशेष रूप से लाइन-बाय-लाइन काम करते हैं, जैसे कि awk, grep, wc, ... POSIX भी न्यूनतम न्यूनतम लाइन लंबाई को परिभाषित करता है, इसलिए सिद्धांत रूप में एक लाइन-ओरिएंटेड टूल अत्यधिक बड़ी लाइनों से निपटने के लिए मना कर सकता है।)
जेन्स

2
@ स्टीफनचेज़ेलस यह जवाब भी जीभ-इन-गाल के रूप में था। लगता है, मौसम के बावजूद, कुछ लोगों को मस्ती से एलर्जी है (आप पर निर्देशित नहीं है; मैं आपके शेल विशेषज्ञता और ओपेंग्रुप मानकों काम करता हूं)।
जेन्स

sed '' < file1 > file2;-)
डिजिटल ट्रॉमा

0

यदि यह काम करता है, तो इसे ठीक न करें।

मै इस्तेमाल करूंगा

cat < file1 > file2

और शब्दार्थ के पीसी को पसीना नहीं।

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