ফাইলনেমগুলির উত্পন্ন তালিকাটি আর্গুমেন্ট তালিকা হিসাবে - স্পেস সহ


16

আমি সংগ্রহ করা ফাইলনামগুলির একটি তালিকা সহ একটি স্ক্রিপ্ট চাওয়ার চেষ্টা করছি find। বিশেষ কিছু নয়, কেবল এইরকম কিছু করা:

$ myscript `find . -name something.txt`

সমস্যাটি হ'ল কয়েকটি পথের নামগুলিতে স্পেস রয়েছে, তাই যুক্তি প্রসারণে এগুলি দুটি অবৈধ নামে বিভক্ত হয়ে যায়। সাধারণত আমি নামগুলি উদ্ধৃতি দিয়ে ঘিরে থাকি তবে এখানে সেগুলি ব্যাককোটি সম্প্রসারণের মাধ্যমে সন্নিবেশ করানো হয়েছে। আমি findপ্রতিটি ফাইলের ফলাফলের আউটপুট ফিল্টার করার চেষ্টা করেছি এবং উদ্ধৃতি দিয়ে চারপাশের ঘিরে রেখেছি , কিন্তু বাশ যখন এগুলি দেখে, তাদের ফেলা করতে খুব দেরি হয়ে গেছে এবং সেগুলি ফাইল নামের অংশ হিসাবে বিবেচনা করা হয়:

$ myscript `find . -name something.txt | sed 's/.*/"&"/'`
No such file or directory: '"./somedir/something.txt"'

হ্যাঁ, কমান্ড লাইনটি কীভাবে প্রক্রিয়াজাত করা যায় তার বিধিগুলি তবে আমি কীভাবে এটি ঘটাব?

এটি বিব্রতকর তবে আমি সঠিক পদ্ধতির সাথে আসতে ব্যর্থ হয়েছি। কীভাবে এটি করা যায় আমি শেষ পর্যন্ত বুঝতে পেরেছি xargs -0 -n 10000... তবে এটি এমন কুৎসিত হ্যাক যা আমি এখনও জিজ্ঞাসা করতে চাই: আমি কীভাবে ব্যাককোটি সম্প্রসারণের ফলাফলগুলি উদ্ধৃত করব, বা অন্যভাবে একই প্রভাব অর্জন করব?

সম্পাদনা: আমি এই বিষয়টি সম্পর্কে বিভ্রান্ত হয়ে পড়েছিলাম যে সমস্ত আর্গুমেন্টকে একক যুক্তির তালিকায় সংগ্রহ xargs করে না, যদি না তা বলা হয় বা সিস্টেমের সীমা অতিক্রম না করে। আমাকে সরাসরি সেট করার জন্য সবার ধন্যবাদ! অন্যেরা, আপনি গ্রহণযোগ্য উত্তরটি পড়ার সাথে সাথে এটি মনে রাখবেন কারণ এটি খুব সরাসরি নির্দেশিত নয়।

আমি উত্তরটি গ্রহণ করেছি, তবে আমার প্রশ্নটি রয়ে গেছে: ব্যাকটিক (বা $(...)) প্রসারণে ফাঁকা স্থান রক্ষার কোনও উপায় নেই ? (দ্রষ্টব্য যে গৃহীত সমাধানটি একটি নন-ব্যাশ উত্তর)।


আমি অনুমান করি যে শেলটি ফাইলের নাম বিভাজক হিসাবে কী ব্যবহার করে তা পরিবর্তন করতে হবে (উদাহরণস্বরূপ, আইএফএসের মান দিয়ে খেলে, একটি সম্ভাব্য উপায় হ'ল IFS="নিউলাইন, ")। তবে কি সমস্ত ফাইলের নামের উপরে স্ক্রিপ্ট চালানো দরকার ? যদি তা না হয় তবে প্রতিটি ফাইলের জন্য স্ক্রিপ্টটি সম্পাদন করতে নিজেকে সন্ধান করুন consider
এনজেএসজি

আইএফএস পরিবর্তন করা একটি দুর্দান্ত ধারণা, এটি নিয়ে ভাবেননি! কমান্ডলাইন ব্যবহারের জন্য ব্যবহারিক নয়, তবে এখনও। :-) এবং হ্যাঁ, লক্ষ্যটি আমার স্ক্রিপ্টের একই অনুরোধে সমস্ত যুক্তিগুলি পাস করা।
অ্যালেক্সিস

উত্তর:


12

আপনি এর কিছু বাস্তবায়ন findএবং এর xargsমতো ব্যবহার করে নিম্নলিখিতটি করতে পারেন ।

$ find . -type f -print0 | xargs -r0 ./myscript

বা, মানকভাবে, ঠিক find:

$ find . -type f -exec ./myscript {} +

উদাহরণ

বলুন আমি নীচের নমুনা ডিরেক্টরি আছে।

$ tree
.
|-- dir1
|   `-- a\ file1.txt
|-- dir2
|   `-- a\ file2.txt
|-- dir3
|   `-- a\ file3.txt
`-- myscript

3 directories, 4 files

এখন বলি আমার কাছে এটি আছে ./myscript

#!/bin/bash

for i in "$@"; do
    echo "file: $i"
done

এখন যখন আমি নিম্নলিখিত কমান্ডটি চালাচ্ছি।

$ find . -type f -print0 | xargs -r0 ./myscript 
file: ./dir2/a file2.txt
file: ./dir3/a file3.txt
file: ./dir1/a file1.txt
file: ./myscript

বা আমি যখন দ্বিতীয় ফর্মটি ব্যবহার করি তখন:

$ find . -type f -exec ./myscript {} +
file: ./dir2/a file2.txt
file: ./dir3/a file3.txt
file: ./dir1/a file1.txt
file: ./myscript

বিস্তারিত

xargs সন্ধান করুন

উপরোক্ত 2 টি পদ্ধতি যদিও দেখতে পৃথক দেখাচ্ছে তবে মূলত একই। প্রথমটি আউটপুটটি সন্ধান থেকে নিচ্ছে, এটি স্যুইচের \0মাধ্যমে নুল ( ) ব্যবহার করে বিভক্ত করছে -print0xargs -0বিশেষভাবে ইনপুট নিতে যে NULLs মানের ব্যবহার বিভক্ত ডিজাইন করা হয়েছে। যে অ-মানক সিনট্যাক্স গনুহ প্রবর্তন করেন findএবং xargsকিন্তু সাম্প্রতিকতম BSD গুলোর মত অন্য কয়েকজন ইদানিং পাওয়া যায়। -rবিকল্প কলিং এড়ানোর জন্য প্রয়োজন বোধ করা হয় myscriptযদি findগনুহ অনুসন্ধানটি কিছুই findকিন্তু BSD গুলোর সাথে নয়।

দ্রষ্টব্য: এই সম্পূর্ণ পদ্ধতির উপর নির্ভর করে যে আপনি কখনই খুব দীর্ঘ যে স্ট্রিংটি পাস করবেন না। যদি এটি হয়, তবে এর দ্বিতীয় অনুরোধটি ./myscriptফলাফলের পরবর্তী ফলাফলগুলি খুঁজে পাওয়া থেকে সরিয়ে দেওয়া হবে।

+ দিয়ে সন্ধান করুন

এটি স্ট্যান্ডার্ড উপায় (যদিও এটি কেবলমাত্র GNU বাস্তবায়নে তুলনামূলকভাবে সম্প্রতি যুক্ত হয়েছিল (2005) find)। আমরা যা করছি তা করার ক্ষমতা xargsআক্ষরিক অর্থে অন্তর্নির্মিত find। সুতরাং findফাইলগুলির একটি তালিকা সন্ধান করবে এবং তারপরে সুনির্দিষ্ট কমান্ডের পরে যতগুলি আর্গুমেন্ট যথাযথভাবে উপস্থাপিত হবে সেই তালিকাটি পাস করবে -exec(নোটটি যে এই ক্ষেত্রে {}কেবলমাত্র শেষ হতে পারে +), প্রয়োজনে কয়েকবার কমান্ড চালনা করে।

কোন উদ্ধৃতি কেন?

প্রথম উদাহরণে আমরা আর্গুমেন্টগুলি পৃথক করার জন্য NULL ব্যবহার করে উদ্ধৃতি দিয়ে সমস্যাগুলি সম্পূর্ণ এড়িয়ে একটি শর্টকাট নিচ্ছি। xargsএই তালিকাটি যখন দেওয়া হয় তখন এটি আমাদের পৃথক কমান্ডের পরমাণুগুলি কার্যকরভাবে রক্ষা করার জন্য NUL গুলি বিভক্ত করার নির্দেশ দেয়।

দ্বিতীয় উদাহরণে আমরা ফলাফলগুলি অভ্যন্তরীণভাবে রাখছি findএবং সুতরাং এটি প্রতিটি ফাইলের পরমাণু কী তা তা জানে এবং সেগুলি যথাযথভাবে হ্যান্ডেল করার গ্যারান্টি দেবে, যার ফলে তাদের উদ্ধৃতি দেওয়ার গোপনীয় ব্যবসায়টি এড়ানো হবে।

কমান্ড লাইনের সর্বোচ্চ আকার?

এই প্রশ্নটি সময়ে সময়ে উঠে আসে তাই বোনাস হিসাবে আমি এই উত্তরে এটিকে যুক্ত করছি, প্রধানত তাই আমি এটি ভবিষ্যতে খুঁজে পেতে পারি। আপনি xargsপরিবেশের সীমাটি কী পছন্দ করে তা দেখতে ব্যবহার করতে পারেন:

$ xargs --show-limits
Your environment variables take up 4791 bytes
POSIX upper limit on argument length (this system): 2090313
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2085522
Size of command buffer we are actually using: 131072

1
ধন্যবাদ তবে আমার সমস্ত যুক্তি আমার স্ক্রিপ্টের একই অনুরোধে পাস করতে হবে । এটি সমস্যার বর্ণনায় রয়েছে, তবে আমি অনুমান করি যে আমি এটি স্পষ্ট করে বলিনি যে এটি ঘটনাগত নয়।
Alexis

@ অ্যালেক্সিস - উত্তরগুলি আবার পড়ুন, তারা আপনার স্ক্রিপ্টের একক কলে সমস্ত যুক্তি প্রেরণ করছে।
slm

ধিক্কার দেব! আমি সম্পর্কে জানেন না +আর্গুমেন্ট প্রাপ্ত করতে find(এবং আপনি ব্যবহার +গদ্য খুব, তাই আমি আপনার ব্যাখ্যা প্রথমবার মিস)। তবে আরও বেশি কথা, আমি xargsডিফল্টরূপে কী করে তা ভুল বুঝতাম !!! ইউনিক্স ব্যবহারের তিন দশকের মধ্যে আমি এখনও অবধি এর আগে কখনও ব্যবহার করিনি, তবে আমি ভেবেছিলাম আমার টুলবক্সটি আমি জানতাম ...
অ্যালেক্সিস

@ অ্যালেক্সিস - আমি অনুভব করেছি যে আমরা কী বলছিলাম তা আপনি মিস করবেন। হ্যাঁ xargsহুকুমের শয়তান। findতারা এটি করতে পারে তা ছড়িয়ে দেওয়ার জন্য আপনাকে এটি পড়তে হবে এবং ম্যান পৃষ্ঠাগুলি বহুবার। সুইচগুলি মে একে অপরের বিপরীত-ধনাত্মক হয় যাতে বিভ্রান্তি বাড়িয়ে তোলে।
SLM

@ অ্যালেক্সিস - এছাড়াও টুল বাক্সে যুক্ত করার জন্য আরও একটি জিনিস, নেস্টেড কমান্ডগুলি চালানোর জন্য ব্যাককোটস / ব্যাকটিক্স ব্যবহার করবেন না, $(..)পরিবর্তে এখনই ব্যবহার করুন। এটি স্বয়ংক্রিয়ভাবে উদ্ধৃতি ইত্যাদির বাসা বাঁধে Back ব্যাকটিকগুলি হ্রাস করা হচ্ছে।
SLM

3
find . -name something.txt -exec myscript {} +

উপরে সালে findসমস্ত মিলে যাওয়া ফাইলের নাম খুঁজে পায় এবং তাদের আর্গুমেন্ট হিসাবে প্রদান করে myscript। শূন্যস্থান বা অন্য কোনও বিজোড় অক্ষর নির্বিশেষে ফাইলের নামের সাথে এটি কাজ করে।

সমস্ত ফাইলের নাম যদি একটি লাইনে ফিট করে তবে মাইক্রিপ্টটি একবার কার্যকর করা হয়। শেলটি হ্যান্ডেল করার জন্য যদি তালিকাটি দীর্ঘ হয় তবে প্রয়োজন অনুসারে একাধিকবার ম্যাসক্রিপ্টটি সন্ধান করুন।

আরও: কমান্ড লাইনে কতগুলি ফাইল ফিট হয়? man findবলে যে findএটি কমান্ড লাইনগুলি "যেভাবে xargs এটি নির্মাণ করে" ঠিক একইভাবে তৈরি করে "। এবং, man xargsসীমাটি সিস্টেম নির্ভর এবং আপনি এগুলি চালিয়ে নির্ধারণ করতে পারেন xargs --show-limits। ( getconf ARG_MAXএটিও একটি সম্ভাবনা)। লিনাক্সে, সীমাটি সাধারণত (তবে সর্বদা নয়) প্রতি কমান্ড লাইনে প্রায় 2 মিলিয়ন অক্ষর।


2

@ স্ল্যামের উত্তম উত্তরে কয়েকটি যোগ

আর্গুমেন্টের আকারের সীমাবদ্ধতাটি execve(2)সিস্টেম কলে রয়েছে (আসলে এটি আর্গুমেন্ট এবং পরিবেশের স্ট্রিং এবং পয়েন্টারগুলির ক্রম আকারের উপর) size যদি myscriptআপনার শেলটি ব্যাখ্যা করতে পারে এমন কোনও ভাষায় লিখিত হয়, তবে সম্ভবত আপনার এটি চালানোর দরকার নেই , আপনার শেলটি অন্য কোনও অনুবাদককে মৃত্যুদণ্ড না দিয়ে কেবল তার ব্যাখ্যা করতে পারে।

আপনি যদি স্ক্রিপ্টটি চালিত হন:

(. myscript x y)

এটা দেখতে:

myscript x y

এটিকে বর্তমান শেলের একটি শিশু দ্বারা এটি ব্যাখ্যা করার পরিবর্তে এটি কার্যকর করার পরিবর্তে (যার মধ্যে শেষ পর্যন্ত মৃত্যুদন্ড কার্যকর করা sh (অথবা সে-ব্যাং লাইনটি যদি নির্দিষ্ট করে তবে আরও বেশি যুক্তি দিয়ে) জড়িত) cept

এখন এ বিষয়টি স্পষ্ট, আপনি ব্যবহার করতে পারবেন না find -exec {} +সঙ্গে .কমান্ড, যেমন .শেল একটি builtin কমান্ড হচ্ছে না, তা শেল দ্বারা নিষ্পন্ন করা হবে না হয়েছে find

সহ zsh, এটি সহজ:

IFS=$'\0'
(. myscript $(find ... -print0))

বা:

(. myscript ${(ps:\0:)"$(find ... -print0)"}

যদিও এর সাথে zsh, আপনার findপ্রথম স্থানের প্রয়োজন হবে না কারণ এর বেশিরভাগ বৈশিষ্ট্যগুলি zshগ্লোববিংয়ে অন্তর্নির্মিত ।

bashভেরিয়েবলগুলিতে NUL টি অক্ষর থাকতে পারে না, সুতরাং আপনাকে অন্য কোনও উপায় খুঁজে বের করতে হবে। একটি উপায় হতে পারে:

files=()
while IFS= read -rd '' -u3 file; do
  files+=("$file")
done 3< <(find ... -print0)
(. myscript "${files[@]}")

এছাড়াও আপনি সঙ্গে globbing zsh ধাঁচের রিকার্সিভ ব্যবহার হতে পারে globstarবিকল্প bash4.0 এবং পরে:

shopt -s globstar failglob dotglob
(. myscript ./**/something.txt)

নোট করুন যে **এটি bash4.3-এ স্থির না হওয়া পর্যন্ত ডিরেক্টরিগুলিতে প্রতিলিঙ্কগুলি অনুসরণ করেছে । এছাড়াও লক্ষ করুন যে গ্লোব্বিং বাছাইপর্ব bashবাস্তবায়ন করে না zshতাই আপনি findসেখানে সমস্ত বৈশিষ্ট্য পাবেন না ।

অন্য বিকল্প হ'ল জিএনইউ ব্যবহার করা ls:

eval "files=(find ... -exec ls -d --quoting-style=shell-always {} +)"
(. myscript "${files[@]}")

আপনি একবারে একবারেই মৃত্যুদন্ড কার্যকর করা হয়েছে কিনা myscriptতা নিশ্চিত করতে চাইলে উপরোক্ত পদ্ধতিগুলিও ব্যবহার করা যেতে পারে (যুক্তি তালিকা খুব বড় হলে ব্যর্থ হয়)। লিনাক্সের সাম্প্রতিক সংস্করণগুলিতে আপনি যুক্তি তালিকায় সেই সীমাবদ্ধতা বাড়াতে এবং এমনকি তুলতে পারেন:

ulimit -s 1048576

(1 জিআইবি স্ট্যাকের আকার, এর এক চতুর্থাংশ আর্গ + এনভিভি তালিকার জন্য ব্যবহার করা যেতে পারে)।

ulimit -s unlimited

(সীমাহীন)


1

সবচেয়ে সিস্টেম, একটি কমান্ড কোনও প্রোগ্রাম প্রেরণ ব্যবহার দৈর্ঘ্যের উপর একটি সীমা xargsবা -exec command {} +। থেকে man find:

-exec command {} +
      This  variant  of the -exec action runs the specified command on
      the selected files, but the command line is built  by  appending
      each  selected file name at the end; the total number of invoca
      tions of the command will  be  much  less  than  the  number  of
      matched  files.   The command line is built in much the same way
      that xargs builds its command lines.  Only one instance of  `{}'
      is  allowed  within the command.  The command is executed in the
      starting directory.

আমন্ত্রণগুলি অনেক কম হবে, তবে এক হওয়ার নিশ্চয়তা নেই। আপনার যা করা উচিত তা হ'ল কমান্ডলাইন আর্গুমেন্টের উপর ভিত্তি করে স্টিডিন থেকে স্ক্রিপ্টের NUL পৃথক করা ফাইল নামগুলি পড়া -o -। আমি এরকম কিছু করব:

$ find . -name something.txt -print0 | myscript -0 -o -

এবং myscriptসেই অনুযায়ী বিকল্প যুক্তি প্রয়োগ করুন ।


হ্যাঁ, ওএস আর্গুমেন্টগুলির সংখ্যা / আকারের ক্ষেত্রে একটি সীমা চাপিয়েছে passed আধুনিক Linux সিস্টেমের এই (রাক্ষুসে) (হয় linux.die.net/man/2/execve ) (স্ট্যাকের আকার 1/4, 0x7FFFFFFF আর্গুমেন্ট)। আফাইক বাশ নিজেই কোনও সীমা চাপায় না। আমার তালিকাগুলি অনেক ছোট, এবং সমস্যাটি কীভাবে xargsকাজ করে তা ভুল বোঝাবুঝি বা স্মরণে রাখার কারণে হয়েছিল । আপনার সমাধানটি প্রকৃতপক্ষে সবচেয়ে মজবুত, তবে এটি এক্ষেত্রে অত্যধিক দক্ষ।
Alexis

0

ব্যাকটিক (বা ... (...)) বিস্তৃতিতে ফাঁকা স্থান রক্ষার কোনও উপায় নেই?

না, নেই। তা কেন?

কোনটি সুরক্ষিত করা উচিত এবং কোনটি করা উচিত নয় তা বাশের কোনও উপায় নেই

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

সুতরাং আপনি যদি অ্যারে চান তবে আপনাকে যা করতে হবে তা হল একটি অ্যারে রয়েছে এমন একটি বাইট ফর্ম্যাটটি সংজ্ঞায়িত করা এবং এটি যা সরঞ্জামগুলি পছন্দ করে xargsএবং findকরতে পারে: আপনি যদি তাদেরকে -0যুক্তি দিয়ে চালান , তারা বাইনারি অ্যারে ফর্ম্যাট অনুসারে কাজ করে যা উপাদানগুলি সমাপ্ত করে নাল বাইট, অন্যথায় অস্বচ্ছ বাইট প্রবাহে শব্দার্থ যুক্ত করে।

দুর্ভাগ্যক্রমে, bashনাল বাইটে স্ট্রিংগুলি বিভক্ত করার জন্য কনফিগার করা যায় না। আমাদের তা পারার জন্য /unix//a/110108/17980 ধন্যবাদ zsh

xargs

আপনি চান আপনার আদেশটি একবার চালিত হোক এবং আপনি বলেছিলেন যে xargs -0 -n 10000আপনার সমস্যার সমাধান করে। এটি নয়, এটি নিশ্চিত করে যে আপনার যদি 10000 এর বেশি পরামিতি থাকে তবে আপনার কমান্ডটি একাধিকবার চলবে।

আপনি যদি এটিকে কঠোরভাবে একবার চালাতে চান বা ব্যর্থ করতে চান তবে আপনাকে -xআর্গুমেন্ট এবং -nআর্গুমেন্টের চেয়ে বড় -sআর্গুমেন্ট সরবরাহ করতে হবে (সত্যই: যথেষ্ট বড় যে শূন্য-দৈর্ঘ্যের আর্গুমেন্টের পুরো গুচ্ছ প্লাস কমান্ডের নামটি ফিট না করে) -sসাইজ)। ( ম্যান xargs , খুব নীচে অংশ দেখুন)

আমি বর্তমানে যে সিস্টেমে আছি তাতে একটি স্ট্যাক প্রায় 8 এম এর মধ্যে সীমাবদ্ধ রয়েছে, তাই এখানে আমার সীমাবদ্ধতা রয়েছে:

$ printf '%s\0' -- {1..1302582} | xargs -x0n 2076858 -s 2076858 /bin/true
xargs: argument list too long
$ printf '%s\0' -- {1..1302581} | xargs -x0n 2076858 -s 2076858 /bin/true
(no output)

সজোরে আঘাত

আপনি যদি কোনও বাহ্যিক কমান্ড জড়িত না করতে চান তবে /unix//a/110108/17980-এ দেখানো হয়েছে এমন অ্যারে ফিডিং-র লুপ, এ জিনিসগুলিকে বিভক্ত করার একমাত্র উপায় ash নাল বাইট

( . ... "$@" )স্ট্যাক আকারের সীমাটি এড়ানোর জন্য স্ক্রিপ্ট উত্সের ধারণাটি দুর্দান্ত (আমি চেষ্টা করে দেখলাম, এটি কার্যকর!) তবে সাধারণ পরিস্থিতির জন্য সম্ভবত এটি গুরুত্বপূর্ণ নয়।

প্রক্রিয়া পাইপের জন্য একটি বিশেষ এফডি ব্যবহার করা গুরুত্বপূর্ণ যদি আপনি স্টিডিনের থেকে অন্য কিছু পড়তে চান তবে অন্যথায় আপনার এটির প্রয়োজন হবে না।

সুতরাং, প্রতিদিনের পরিবারের প্রয়োজনের জন্য সহজতম "দেশীয়" উপায়:

files=()
while IFS= read -rd '' file; do
    files+=("$file")
done <(find ... -print0)

myscriptornonscript "${files[@]}"

আপনি যদি আপনার প্রক্রিয়া গাছটি পরিষ্কার এবং দেখতে ভাল পছন্দ করেন তবে এই পদ্ধতিটি আপনাকে তা করতে দেয় exec mynonscript "${files[@]}", যা বাশ প্রক্রিয়াটিকে মেমরি থেকে সরিয়ে দেয়, নামক কমান্ডের সাথে প্রতিস্থাপন করে। xargsডেকে আনা কমান্ডটি চালিত হওয়ার সময় সর্বদা স্মৃতিতে থাকবে, এমনকি যদি কমান্ডটি কেবল একবার চালিত হয়।


নেটিভ বাশ পদ্ধতির বিরুদ্ধে যা কথা বলে তা হ'ল:

$ time { printf '%s\0' -- {1..1302581} | xargs -x0n 2076858 -s 2076858 /bin/true; }

real    0m2.014s
user    0m2.008s
sys     0m0.172s

$ time {
  args=()
  while IFS= read -rd '' arg; do
    args+=( "$arg" )
  done < <(printf '%s\0' -- $(echo {1..1302581}))
  /bin/true "${args[@]}"
}
bash: /bin/true: Argument list too long

real    107m51.876s
user    107m38.532s
sys     0m7.940s

বাশ অ্যারে হ্যান্ডলিংয়ের জন্য অনুকূলিত হয় না।


ম্যান xargs :

-n সর্বাধিক আরোগুলি

প্রতি কমান্ড লাইনে সর্বাধিক সর্বাধিক-আর্গুমেন্ট যুক্তি ব্যবহার করুন। -X বিকল্পটি দেওয়া না হলে, যদি আকার (-s বিকল্পটি দেখুন) ছাড়িয়ে যায় তবে সর্বাধিক-আরগ্সের চেয়ে কম আর্গুমেন্ট ব্যবহৃত হবে।

-স সর্বোচ্চ অক্ষর

কমান্ড এবং প্রারম্ভিক-আর্গুমেন্ট এবং আর্গুমেন্ট স্ট্রিংয়ের শেষে শেষ হওয়া নালস সহ কম্যান্ড লাইন প্রতি সর্বাধিক সর্বাধিক অক্ষর ব্যবহার করুন Use বৃহত্তম অনুমোদিত অনুমোদিত মান হ'ল সিস্টেম-নির্ভর, এবং নির্বাহের জন্য যুক্তির দৈর্ঘ্য সীমা হিসাবে গণনা করা হয়, আপনার পরিবেশের আকার কম, হেডরুমের কম 2048 বাইট। যদি এই মানটি 128KiB এর বেশি হয় তবে 128Kib ডিফল্ট মান হিসাবে ব্যবহৃত হয়; অন্যথায়, ডিফল্ট মান সর্বাধিক is 1KiB 1024 বাইট।

-এক্স

আকার (-s বিকল্পটি দেখুন) ছাড়িয়ে গেলে প্রস্থান করুন।


সমস্ত সমস্যার জন্য ধন্যবাদ তবে আপনার প্রাথমিক ভিত্তি এই সত্যটিকে উপেক্ষা করে যে বাশ সাধারণত কোট প্রসেসিংয়ের একটি বিস্তৃত পদ্ধতি ব্যবহার করে। তবে ব্যাককোট সম্প্রসারণে নয়। নিম্নলিখিতগুলির সাথে তুলনা করুন (যা উভয়ই ত্রুটি দেয় তবে পার্থক্য দেখায়): ls "what is this"বনাম ls `echo '"what is this"'` । কেউ ব্যাককোটের ফলাফলের জন্য উদ্ধৃতি প্রক্রিয়াকরণ বাস্তবায়ন করতে অবহেলিত।
অ্যালেক্সিস

আমি আনন্দিত ব্যাককোটগুলি উদ্ধৃতি প্রক্রিয়াকরণ না করে। এমনকি তারা শব্দ বিভাজনও করে এমনটি আধুনিক কম্পিউটারের ইতিহাসে যথেষ্ট বিভ্রান্ত চেহারা, মাথা-স্ক্র্যাচিং এবং সুরক্ষা ত্রুটিগুলির কারণ ঘটেছে।
ক্লেক

প্রশ্নটি হল "ব্যাকটিক (বা $(...)) সম্প্রসারণে স্পেসগুলি রক্ষার কোনও উপায় নেই ?", সুতরাং সেই পরিস্থিতিতে করা হয়নি এমন প্রক্রিয়াজাতিকে উপেক্ষা করা উপযুক্ত বলে মনে হয়।
ক্লেক

নাল-টার্মিনেটেড এলিমেন্ট অ্যারে ফর্ম্যাটটি হ'ল একটি অ্যারের প্রকাশ করার সহজতম এবং তাই নিরাপদ উপায়। এটি কেবল একটি লজ্জা যা bashএটিকে স্থানীয়ভাবে সমর্থন করে না যেমন দৃশ্যত zsh
ক্লেক

প্রকৃতপক্ষে, এই সপ্তাহে আমি ব্যবহার করেছি printf "%s\0"এবং xargs -0একটি উদ্ধৃতি পরিস্থিতি ঘুরে দেখছি যেখানে একটি মধ্যবর্তী সরঞ্জাম শেল দ্বারা পার্স করা স্ট্রিংয়ের মাধ্যমে পরামিতিগুলি পাস করবে। উদ্ধৃতি সর্বদা আপনাকে কামড়ানোর জন্য ফিরে আসে।
ক্লেক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.