আইও পুনঃনির্দেশ এবং হেড কমান্ড


9

আমি .hgignoreআজ সাইগউইন বাশ শেল থেকে একটি ফাইল দ্রুত সম্পাদনা করার চেষ্টা করছিলাম এবং আমি একটি লাইন যুক্ত করেছি যা একটি ভুল ছিল। আমি এটি নিশ্চিত না যে এটি করার সর্বোত্তম উপায়টি ছিল কিনা তবে আমি তাড়াতাড়ি head -1 .hgignoreআপত্তিজনক লাইনটি অপসারণ করার জন্য ব্যবহার করার কথা ভেবেছিলাম (ফাইলটিতে আমার আগে কেবল একটি লাইন ছিল)) নিশ্চিতভাবেই, কার্যকর করা হলে এটি একমাত্র আউটপুট হিসাবে প্রথম লাইন দেয়।

কিন্তু যখন আমি আউটপুটটি পুনর্নির্দেশ করার চেষ্টা করে এবং ফাইলটি পুনরায় লেখার চেষ্টা করেছিলাম তখন head -1 .hgignore > .hgignoreফাইলটি খালি ছিল। কেন এমন হয়? পরিবর্তে যদি আমি যুক্ত করার চেষ্টা করি head -1 .hgignore >> .hgignore, তবে এটি সঠিকভাবে সংযোজন করে তবে এটি অবশ্যই পছন্দসই ফলাফল নয়। এই ক্ষেত্রে কেন একটি ছাঁটাই পুনর্নির্দেশ কাজ করে না?


উত্তর:


10

শেল মত একটি কমান্ড লাইন পায় কখন: command > file.outশেল নিজেই প্রর্দশিত (এবং হয়ত সৃষ্টি) ফাইল নামে file.out। খোলা থেকে পাওয়া ফাইল ফাইলের বর্ণনাটিতে শেল ফাইল বর্ণনাকারী 0 সেট করে। I / O পুনঃনির্দেশটি এভাবে কাজ করে: প্রতিটি প্রক্রিয়া 0, 1 এবং 2 ফাইল বর্ণনাকারী সম্পর্কে জানে।

এটি সম্পর্কে হার্ড অংশটি কীভাবে খুলতে হয় file.out। বেশিরভাগ সময়, আপনি file.outঅফসেট 0 এ লিখতে চাইছেন (অর্থাত কাটা) এবং শেলটি এটি আপনার জন্য করেছিল। এটি সঙ্কুচিত .hgignore, লেখার জন্য এটি খোলার জন্য, ফাইলডিসিপ্টরকে 0 তে দোষ দিয়েছেন, তারপরে মৃত্যুদন্ড কার্যকর করা হয়েছে head। তাত্ক্ষণিক ফাইল ক্লোবার্বিং।

ব্যাশ শেল এ, আপনি set noclobberএই আচরণটি পরিবর্তন করতে একটি করুন ।


আহা, দেখছি। আমি ভেবেছিলাম যে কমান্ডটি চালানোর আগে শেলটি ফাইলটি ছাঁটাই করছে, তবে কেন জানি না। ব্যাখ্যার জন্য ধন্যবাদ!
voithos

10

আমি মনে করি ব্রুস এখানে শেল পাইপলাইন দিয়ে কী চলছে তার উত্তর দেয় ।

আমার পছন্দের ছোট্ট ইউটিলিটিগুলির মধ্যে একটি হ'ল মুর্টিলsponge থেকে প্রাপ্ত আদেশ । টার্গেট আউটপুট ফাইলটি খোলার আগে এবং ডেটা লেখার আগে এটি সমস্ত উপলভ্য ইনপুট "ভিজিয়ে" ঠিক এই সমস্যার সমাধান করে। এটি আপনাকে পাইপলাইনগুলি ঠিক কীভাবে প্রত্যাশা করেছিল তা লেখার অনুমতি দেয়:

$ head -1 .hgignore | sponge .hgignore

দরিদ্র লোকটির সমাধান হ'ল আউটপুটটিকে একটি অস্থায়ী ফাইলে পাইপ করা হয়, তারপরে পাইপলাইনটি শেষ হওয়ার পরে (উদাহরণস্বরূপ আপনি চালিত পরবর্তী কমান্ডটি) টেম্প ফাইলটি মূল ফাইলের জায়গায় ফিরে যেতে হয়।

$ head -1 .hgingore > .hgignore.tmp
$ mv .hgignore{.tmp,}

কয়েক বছর পরে এটির দিকে তাকিয়ে আমার মনে একটি চিন্তাভাবনা ঘটেছিল: আমরা কি তা করতে পারি না head -1 .hgignore | tee .hgignore? teeকোর্টিলগুলিতে রয়েছে, এবং পার্ক / পার্শ্ব-প্রতিক্রিয়া হিসাবে, এটি STDOUT- এও লিখেছেন
voithos

@ অভিটোস আমার জ্ঞান অনুসারে teeএটি যে ফাইলটি লিখে চলেছে তা অন্য কিছুর মতোই খোলা এবং ছেঁটে ফেলেছে যাতে আপনি লেখার সাথে সংক্ষিপ্ত হওয়ার আগে ফাইলের বিষয়বস্তু পড়ার রেস শর্তের মূল সমস্যাটি এখানে সমাধান করে না।
কালেব

আপনি এমন একটি বক্তব্য তুলে ধরেছেন যা সম্পর্কে আমি অবগত ছিলাম না - যথা - পাইপযুক্ত কমান্ডগুলি তাত্ক্ষণিকভাবে পরিবর্তে, শুরু করা হয়েছিল। এটা কি সঠিক? আমি হয়নি যদিও, পরীক্ষা এবং tee বলে মনে হয় পছন্দসই জিনিস না। আমি 8.13আমার মেশিনে সংস্করণ পেয়েছি ।
voithos

1
@ ওভিটোস হ্যাঁ একটি পাইপলাইনে কমান্ড এবং জড়িত সমস্ত ইনপুট / আউটপুট চ্যানেলগুলি বিপরীত ক্রমে শুরু করা হয়েছে যাতে পাইপলাইনটি যখন প্রথমটি দেওয়া শুরু করে তখন ডেটা পেতে প্রস্তুত হয়। আমি সন্দেহ করি যে আপনার পরীক্ষাটি ত্রুটিযুক্ত কারণ আপনি সম্ভবত খুব অল্প পরিমাণে ডেটা ব্যবহার করেছেন এবং এটি আপনার প্রয়োজনীয়তার আগে পুরো জিনিসটি একটি রিড বাফারে ক্যাশে পেয়েছিল। teeপ্রোগ্রামটি আপনার ফাইল অগ্রভাগ ছাঁটিয়া হবে, এটি তাদের বাফার দ্বিগুণ করার জন্য সেটআপ নয়।
কালেব

3

ভিতরে

head -n 1 file > file

fileheadশুরু হওয়ার আগেই কেটে ফেলা হয় তবে আপনি যদি এটি লিখেন:

head -n 1 file 1<> file

এটি fileরিড-রাইট মোডে খোলার মতো নয় । যাইহোক, headলেখার কাজ শেষ করার পরে, এটি ফাইলটি ছাঁটাই করে না, সুতরাং উপরের লাইনটি কোনও অপ-বিকল্প headহবে ( কেবলমাত্র নিজের উপরের প্রথম লাইনটি পুনরায় লেখবে এবং অন্যগুলিটি অপছন্দ করবে)।

যাইহোক, পরে headফিরে আসার পরে এবং fdএখনও খোলা থাকা অবস্থায় আপনি অন্য একটি কমান্ড কল করতে পারেন যা এটি করে truncate

এই ক্ষেত্রে:

{ head -n 1 file; perl -e 'truncate STDOUT, tell STDOUT'; } 1<> file

কি এখানে গুরুত্বপূর্ণ যে truncateউপরে, headশুধু মাত্র প্রথম লাইন পর FD 1 টি ফাইল ভিতরে জন্য কার্সার চলে আসে। এটি আমাদের প্রথম লাইনের পুনর্লিখন করে যা আমাদের এটির দরকার ছিল না, তবে এটি ক্ষতিকারক নয়।

পসিক্স হেডের সাহায্যে আমরা সেই প্রথম লাইনটি আবার না লিখেই পালাতে পারি:

{ head -n 1 > /dev/null
  perl -e 'truncate STDIN, tell STDIN'
} <> file

এখানে, আমরা সত্যটি ব্যবহার করছি যা headতার স্টিনে কার্সার অবস্থানকে সরিয়ে দেয়। যদিও headসাধারণত পারফরম্যান্সের উন্নতি করতে বড় খন্ডে তার ইনপুট পড়তে হবে, POSIX তা (যেখানে সম্ভব) করতে হবে seekমাত্র প্রথম লাইন পরে ফিরে যদি এটা সে স্থানটি অতিক্রম চলে গেছে। তবে লক্ষ করুন যে সমস্ত বাস্তবায়ন এটি করে না।

বিকল্পভাবে, আপনি readএই ক্ষেত্রে পরিবর্তে শেলের কমান্ডটি ব্যবহার করতে পারেন :

{ read -r dummy; perl -e 'truncate STDIN, tell STDIN'; } <> file

1
স্টিফেন, আপনি একটি প্রমিত জানি বা coreutils কমান্ড যে অগ্রভাগ ছাঁটিয়া পারেন STDINকি আপনি ব্যবহার সম্পন্ন করেছি অনুরূপ perlউপরে
Iruvar

2
@ 1_CR, না যদিও ফাইলের ddযেকোন স্বেচ্ছাসেবী পরম অফসেটে ছাঁটাই করতে পারে । সুতরাং আপনি দ্বিতীয় লাইনের বাইট অফসেট নির্ধারণ করতে পারেন এবং সেখান থেকে dd bs=1 seek="$offset" of=file
ছাঁটাই

1

রিয়েল ম্যান এর সমাধান হল

ed .hgignore
$d
wq

বা ওয়ান-লাইনার হিসাবে

printf '%s\n' '$d' 'wq' | ed .hgignore

বা জিএনইউ সেড সহ:

sed -i '$d' .hgignore

(না, আমি মজা করছি I'd আমি একটি ইন্টারেক্টিভ সম্পাদক ব্যবহার করব। vi .hgignore GddZZ)


আমি ভাবলাম, :wqওভার ব্যবহারের কি কোনও সুবিধা আছে ZZ?
voithos

এছাড়াও, :xযা আমার আঙ্গুলগুলি স্বয়ংক্রিয়ভাবে করে
গ্লেন জ্যাকম্যান

এবং ZQএকই হিসাবে রয়েছে:q!
গ্লেন জ্যাকম্যান

জেডজেড এবং: এক্স কেবল লেখার জন্য যদি কিছু থাকে তবে লিখুন ...: ডব্লিউটি প্রয়োজন না থাকলে ফাইলটিকে সর্বদা ডিস্কে ফাইন্যাস করে। আমি ব্যবহার করি: এক্সএ কারণ আমি ট্যাব ব্যবহার করি।
xenoterracide

1

আপনি প্রাক্তন মোডে ভিম ব্যবহার করতে পারেন:

ex -sc '2,d|x' .hgignore
  1. 2, শেষ পর্যন্ত লাইন 2 নির্বাচন করুন

  2. d মুছে ফেলা

  3. x সংরক্ষণ করেন এবং বন্ধ করেন


0

ইন-প্লেস এডিটিংয়ের জন্য আপনি জার্গেন হিটজেলের দেখানো ওপেন ফাইল হ্যান্ডেল ট্রিকটি সেডের সি / সি / ডি / 'মাইফাইল থেকে মাইফাইলে পুনর্নির্দেশ আউটপুটে ব্যবহার করতে পারেন

exec 3<.hgignore
rm .hgignore  # prevent open file from being truncated
head -1 <&3 > .hgignore

ls -l .hgignore  # note that permissions may have changed

2
এবং rm .hgignoreআপনার শক্তি ব্যর্থ হওয়ার ঠিক কয়েক ঘন্টা পরে কঠোর পরিশ্রম করে। ঠিক আছে, এটির জন্য কিছু আসে যায় না .hgignoreতবে আপনি কেন এমন জটিল কিছু করবেন কেন? সুতরাং আমার ডাউনভোট: প্রযুক্তিগতভাবে সঠিক তবে খুব খারাপ ধারণা।
গিলস'স-অশুভ হওয়া বন্ধ করুন

@ গিলিস, সম্ভবত এতটা ভাল ধারণা নয়, তবে এটি উদাহরণস্বরূপ perl -i(ইনপ্লেস এডিটিংয়ের জন্য) কী করে এবং কিছু বাস্তবায়নও যদি sed -iএটি করে থাকে তবে আমি অবাক হব না (যদিও জিএনইউর সর্বশেষ সংস্করণটি এটি sedমনে হয় না)।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.