স্টিডিন ইনপুট ফাঁকা থাকলে কীভাবে xargs কমান্ড উপেক্ষা করবেন?


188

এই আদেশটি বিবেচনা করুন:

ls /mydir/*.txt | xargs chown root

উদ্দেশ্যটি হ'ল সমস্ত পাঠ্য ফাইলের মালিককে mydirরুটে পরিণত করা

সমস্যাটি হ'ল যদি সেখানে কোনও .txtফাইল না থাকে mydirতবে xargs একটি ত্রুটি ছুঁড়ে বলেছে যে কোনও পাথ নির্দিষ্ট নেই। এটি একটি নিরীহ উদাহরণ, কারণ একটি ত্রুটি নিক্ষেপ করা হচ্ছে, তবে কিছু ক্ষেত্রে, আমার এখানে ব্যবহার করা স্ক্রিপ্টের মতো একটি ফাঁকা পথটি বর্তমান ডিরেক্টরি হিসাবে ধরে নেওয়া হয়। সুতরাং যদি আমি সেই আদেশটি /home/tom/যদি তখন থেকে চালিত করি তবে যদি ফলাফল না থাকে ls /mydir/*.txtএবং সমস্ত ফাইলের অধীনে /home/tom/তাদের মালিকরা রুটে পরিবর্তিত হয়।

তাহলে আমি কীভাবে খালি ফলাফল উপেক্ষা করতে পারি?


6
একদিকে: lsপ্রোগ্রামেটিক ব্যবহারের জন্য পাইপ আউটপুট কখনও না ; দেখতে mywiki.wooledge.org/ParsingLs
চার্লস ডাফি

আমার ব্যবহারের ক্ষেত্রে git branch --merged | grep -v '^* ' | xargs git branch -dএটি খালি
ইনপুটটিতেও

উত্তর:


305

জিএনইউর জন্য xargs, আপনি -rবা --no-run-if-emptyবিকল্পটি ব্যবহার করতে পারেন :

--no-run-if-empty
-r
যদি স্ট্যান্ডার্ড ইনপুটটিতে কোনও ননব্ল্যাঙ্ক থাকে না, কমান্ডটি চালাবেন না। সাধারণত ইনপুট না থাকলেও কমান্ডটি একবার চালানো হয়। এই বিকল্পটি একটি জিএনইউ এক্সটেনশন।


9
আমি প্রথমে গুগলে সৎভাবে অনুসন্ধান করেছি এবং এটি পেয়েছি (তবে ম্যানুয়ালটি না পড়ে জিজ্ঞাসা করা হত না)। আমি ভাবলাম যে এটিকে পূর্বনির্ধারিত আচরণ হতে হবে, এটি সক্ষম করার জন্য কোনও সুইচের দরকার নেই।
জনি জেডি

28
দুর্ভাগ্যক্রমে এটি কোনও ম্যাকের সাথে কাজ করে না। সংক্ষিপ্ত বা দীর্ঘ বিকল্প উভয়ই নয়।
বুড়ি

9
@ ওয়েবেই - ওএসএক্সের বিএসডি ইউজারস্পেস রয়েছে তাই এই ধরণের জিনিসটি ঘন ঘন ঘটবে। আপনি জিএনইউ ফাইল্টিলগুলি ইনস্টল করতে হোমব্রিউ ব্যবহার করে এটির চারপাশে কাজ করতে পারেন।
edk750

7
আপনি বলতে চাচ্ছেন brew install findutilsfindutilsনা fileutils
মিটার

3
ম্যাকোস-তে, যেভাবেই কমান্ড না চালানোর জন্য পতাকা ফলাফল সরবরাহ না করা, সুতরাং আমি অনুমান করি যে এটি কেবল প্রয়োজন নেই।
ট্রেজকাজ

15

অ গনুহ xargs ব্যবহারকারীরা সুবিধা গ্রহণ করতে পারে -L <#lines>, -n <#args>, -i, এবং -I <string>:

ls /empty_dir/ | xargs -n10 chown root # chown executed every 10 args or fewer
ls /empty_dir/ | xargs -L10 chown root # chown executed every 10 lines or fewer
ls /empty_dir/ | xargs -i cp {} {}.bak # every {} is replaced with the args from one input line
ls /empty_dir/ | xargs -I ARG cp ARG ARG.bak # like -i, with a user-specified placeholder

মনে রাখবেন যে জার্গেজগুলি সাদা স্পেসে লাইনটি বিভক্ত করে তবে উদ্ধৃতি দেওয়া এবং পলায়ন পাওয়া যায়; বিশদ জন্য আরটিএফএম।

এছাড়াও, ডোরন বিহার যেমন উল্লেখ করেছেন, এই কাজটি বহনযোগ্য নয় তাই চেকগুলির প্রয়োজন হতে পারে:

$ uname -is
SunOS sun4v
$ xargs -n1 echo blah < /dev/null
$ uname -is
Linux x86_64
$ xargs --version | head -1
xargs (GNU findutils) 4.7.0-git
$ xargs -n1 echo blah < /dev/null
blah

2
প্রশ্নের উত্তর বলে মনে হচ্ছে না?
নিকোলাস রাউল

2
@ নিকোলাস: যদি আপনার সংস্করণটি স্যুইচ xargsসমর্থন না করে --no-run-if-emptyএবং এসটিডিএন ইনপুট ব্যতীত কমান্ড আর্গুমেন্ট চালানোর চেষ্টা না করে তবে এটি কার্যকরকরণ প্রতিরোধের উপায় (সোলারিস 10-তে এটিই রয়েছে)। অন্যান্য ইউনিক্সের সংস্করণগুলি কেবল একটি খালি তালিকা (যেমন এআইএক্স) উপেক্ষা করতে পারে।
এরিয়েলকো

4
হ্যাঁ! ম্যাক ওএসএক্স-তে, echo '' | xargs -n1 echo blahকিছুই করে না; যদিও echo 'x' | xargs -n1 echo blah"ব্লাহ" মুদ্রণ করে।
কার্লোসায়াম

2
জিএনইউ এবং বিএসডি / ওএসএক্স উভয়ের সমর্থনের জন্য আমি ls /mydir/*.txt | xargs -n 1 -I {} chown root {}এই জাতীয় কিছু ব্যবহার করে শেষ করব: যেমন এই উত্তরটি সূচিত করে।
লুস বিয়ানচিন

2
এটি লক্ষ করা উচিত যে echo '' | xargs -n1 echo blahজিএনইউ'র blahসাথে প্রিন্ট করা হয় xargs
ডোরন বেহার

11

man xargsবলে --no-run-if-empty


1
আপনি ওএসএক্স এ থাকলে তা হবে না। আপনি কেন আগ্রহী হন তা যদি edk750 তাদের মন্তব্যে এটি ব্যাখ্যা করেছে has
জেসনলোনহার্ড

9

পদ হিসাবে xargs, আপনি -rপ্রস্তাবিত হিসাবে ব্যবহার করতে পারেন , তবে এটি BSD দ্বারা সমর্থিত নয় xargs

সুতরাং কাজের হিসাবে আপনি কিছু অতিরিক্ত অস্থায়ী ফাইল পাস করতে পারেন, উদাহরণস্বরূপ:

find /mydir -type f -name "*.txt" -print0 | xargs -0 chown root $(mktemp)

অথবা এর স্টডারকে নাল ( 2> /dev/null) এ পুনঃনির্দেশ করুন , যেমন

find /mydir -type f -name "*.txt" -print0 | xargs -0 chown root 2> /dev/null || true

whileলুপ ব্যবহার করে পাওয়া ফাইলগুলির উপরে পুনরাবৃত্তি হ'ল আরও একটি ভাল পদ্ধতির উপায় :

find /mydir -type f -name "*.txt" -print0 | while IFS= read -r -d '' file; do
  chown -v root "$file"
done

আরও দেখুন: ম্যাক ওএস এক্সে এক্সগার্সের খালি ফলাফল উপেক্ষা করুন


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

সুতরাং আপনার নিজের দৃষ্টিভঙ্গি পরিবর্তন করা উচিত এবং findপরিবর্তে কমান্ড ব্যবহার করা উচিত , যেমন

find /mydir -type f -name "*.txt" -execdir chown root {} ';'

1
দুঃখিত, আমি বুঝতে পারি না কীভাবে এটি while IFS= read -r -d '' fileবৈধ। তুমি কি ব্যাখ্যা করতে পারো?
অ্যাড্রিয়ান

2

ওএসএক্স-তে: আর্গুমেন্টের xargsসাথে ডিল করার জন্য বাশ পুনরায় বাস্তবায়ন করুন -r, উদাহরণস্বরূপ এটি লিখুন $HOME/binএবং এতে যুক্ত করুন PATH:

#!/bin/bash
stdin=$(cat <&0)
if [[ $1 == "-r" ]] || [[ $1 == "--no-run-if-empty" ]]
then
    # shift the arguments to get rid of the "-r" that is not valid on OSX
    shift
    # wc -l return some whitespaces, let's get rid of them with tr
    linecount=$(echo $stdin | grep -v "^$" | wc -l | tr -d '[:space:]') 
    if [ "x$linecount" = "x0" ]
    then
      exit 0
    fi
fi

# grep returns an error code for no matching lines, so only activate error checks from here
set -e
set -o pipefail
echo $stdin | /usr/bin/xargs $@

2

এটি জিএনইউ xargs এর একটি আচরণ যা -r, --no-run-if-খালি ব্যবহার করে দমন করা যেতে পারে।

Xargs এর * BSD রূপটি ডিফল্টরূপে এই আচরণ করে, সুতরাং -r প্রয়োজন হয় না। যেহেতু ফ্রিবিএসডি .1.১ (জানুয়ারী ২০০৯ এ প্রকাশিত) সামঞ্জস্যতার কারণে একটি-তর্কটি গৃহীত হয় (ডাইনি কিছুই করেনা)।

আমি ব্যক্তিগতভাবে স্ক্রিপ্টগুলিতে লংপ্যাপ ব্যবহার করতে পছন্দ করি তবে যেহেতু * BSD xargs দীর্ঘতর ব্যবহার করে না কেবল "-r" ব্যবহার করে এবং xargs লিনাক্স সিস্টেমে * BSD এ একই কাজ করবে

ম্যাকোস (বর্তমানে ম্যাকস মোজাভে) -তে xargs দুঃখের সাথে "-r" যুক্তি সমর্থন করে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.