কীভাবে `xargs` তৈরি করবেন তা সন্তানের প্রস্থানটিকে অগ্রাহ্য করুন এবং আরও প্রক্রিয়া চালিয়ে যান


24

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

এমনকি একটি xargsশিশু মারা গেলেও এটি আর কোনও ইনপুট প্রক্রিয়া করে না:

কনসোল 1:

[09:35:48] % seq 40 | xargs -i --max-procs=4 bash -c 'sleep 10; date +"%H:%M:%S {}";'
xargs: bash: terminated by signal 15
09:35:58 3
09:35:58 4
09:35:58 2
<Exit with code 125>

কনসোল 2:

[09:35:54] kill 5601

xargsএকবারে কোনও শিশু প্রক্রিয়াটি মারা যাওয়ার পরে আর কোনও প্রক্রিয়া চালিয়ে যাওয়া থেকে কী কীভাবে আরও ইনপুট প্রক্রিয়াকরণ করা বন্ধ করে দিতে পারি ?


আমি xargs৪.৪.২ সংস্করণ ব্যবহার করছি debian wheezyএবং দেখে মনে হচ্ছে প্রতিটি জিনিস ঠিকঠাক হয়ে যায় এমনকি আমি একটি নির্দিষ্ট sleepপ্রক্রিয়াটি মেরে ফেললেও। আপনি কোন সংস্করণ xargsব্যবহার করছেন? তারা সর্বশেষ সংস্করণে সমস্যাটি স্থির করে থাকতে পারে।
কান্নান মোহন

পার্টিতে কিছুটা দেরি, তবে কীভাবে xargs ... bash -c '...;exit 0'বা এমনকিxargs ... bash -c '... || echo erk'
সামোইন

নোট এটি parallel -j 1একটি সম্ভাব্য হ্যাক সমাধান।
ব্যারিকার্টার

উত্তর:


25

না, আপনি পারবেন না। xargsSavannah.gnu.org-সূত্র থেকে :

if (WEXITSTATUS (status) == CHILD_EXIT_PLEASE_STOP_IMMEDIATELY)
  error (XARGS_EXIT_CLIENT_EXIT_255, 0,
         _("%s: exited with status 255; aborting"), bc_state.cmd_argv[0]);
if (WIFSTOPPED (status))
  error (XARGS_EXIT_CLIENT_FATAL_SIG, 0,
         _("%s: stopped by signal %d"), bc_state.cmd_argv[0], WSTOPSIG (status));
if (WIFSIGNALED (status))
  error (XARGS_EXIT_CLIENT_FATAL_SIG, 0,
         _("%s: terminated by signal %d"), bc_state.cmd_argv[0], WTERMSIG (status));
if (WEXITSTATUS (status) != 0)
  child_error = XARGS_EXIT_CLIENT_EXIT_NONZERO;

সেই চেকের চারপাশে বা ফাংশনটির কাছাকাছি কোনও পতাকা নেই that এটি সর্বাধিক প্রকল্পগুলির সাথে সম্পর্কিত বলে মনে হচ্ছে, যা আমি বোঝার চেষ্টা করি: আপনি যদি সর্বাধিক প্রসকে যথেষ্ট উচ্চরূপে সেট করেন তবে এটি সীমাবদ্ধ না হওয়া পর্যন্ত এটি পরীক্ষা করা বিরক্ত করবে না, যা আপনি কখনই পাবেন না।

আপনি যা করার চেষ্টা করছেন তার আরও ভাল সমাধান হতে পারে জিএনইউ মেক ব্যবহার করুন :

TARGETS=$(patsubst %,target-%,$(shell seq 1 40))

all: $(TARGETS)

target-%:
    sleep 10; date +"%H:%M:%S $*"

তারপর:

$ make -k -j4 

একই প্রভাব ফেলবে এবং আপনাকে আরও ভাল নিয়ন্ত্রণ দেবে।


9

এটি মনে হয় সবচেয়ে স্পষ্ট ভাষায় কথা বলার মধ্যে একটি কেবলমাত্র অন্যান্য প্রস্তাব দ্বারা চিহ্নিত করা হয়।

এটি হল, আপনি নিম্নলিখিত ব্যবহার করতে পারেন:

bash -c '$PROG_WHICH_MAY_FAIL ; (true)'

"সাফল্য জোর" করার জন্য।

দ্রষ্টব্য, এটি লার্নিক্স দ্বারা প্রস্তাবের লাইনের পাশাপাশি রয়েছে (কেবলমাত্র এত কথায় নয়)।

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

bash -c '$PROG_WHICH_MAY_FAIL || touch failed; (true)'

trueএখানে কিছুটা অপ্রয়োজনীয় এবং তাই এই ভাল হিসেবে লেখা যেতে যেতে নাও পারেন:

bash -c '$PROG_WHICH_MAY_FAIL || touch failed'

যেহেতু আমরা সম্ভবত জানতে চাই যে কখন 'ব্যর্থ' ফাইলটি স্পর্শ করা যায়নি। অন্য কথায়, আমরা আর ব্যর্থতা উপেক্ষা করছি না , আমরা নোট নিচ্ছি এবং চালিয়ে যাচ্ছি।

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

পরিশেষে, আমি মনে করি এটিই হ'ল জেমস ইয়ংম্যান সুপারিশের মাধ্যমে trapযা বোঝায় , সম্ভবত এটি একই পদ্ধতিতে ব্যবহার করা যেতে পারে। এটি, সমস্যাটিকে উপেক্ষা করবেন না ... এটিকে ফাঁদে ফেলুন এবং এটি পরিচালনা করুন বা আপনি একদিন জাগ্রত হন এবং দেখতে পান যে উপ-প্রোগ্রামগুলির কোনওটিই মোটেই সফল হয়নি ;-)


3

ব্যবহার trap:

$ seq 40 | xargs -i --max-procs=4 bash -c \
 'trap "echo erk; exit 1" INT TERM;  sleep 10; date +"%H:%M:%S {}";' fnord
16:07:39 2
16:07:39 4
erk
16:07:39 1
^C
erk
erk
erk
erk

বিকল্পভাবে শেল থেকে অন্য ভাষায় স্যুইচ করুন যাতে আপনি সংকেত হ্যান্ডলারগুলিও সেট করতে পারেন।

এও নোট করুন যে bash -c foo..আপনার $0নেওয়া উচিত এমন মান নির্দিষ্ট করার পরে (এখানে, fnord) যাতে উত্পাদিত প্রথম শব্দটি seqনা খেয়ে যায়।


2

মারা যাওয়ার প্রোগ্রামটির সিগন্যালটি 'খাওয়ার' জন্য সেখানে আরও একটি আদেশ দিন Put

আমি আপনার উদাহরণটি চেষ্টা করেছি, প্রাথমিকভাবে সমস্যাটি প্রমাণ করার জন্য দেখানো হয়েছে ... 'কিল্লাল স্লিপ' ঘুমের প্রক্রিয়াটিকে মেরে ফেলেছে, বাশকে বাধা দেয় এবং এক্সার্গস ছাড়ছে।

পরীক্ষা হিসাবে, আমি xargs এবং বাশ এর মধ্যে একটি 'কমান্ড রান করুন' টাইপ কমান্ড আটকেছি ... এই ক্ষেত্রে '/ usr / বিন / সময়'। এবার (কোনও পাং নেই), কিল্লাল স্লিপ ঘুমের প্রক্রিয়াটিকে মেরে ফেলবে, তবে জার্গসগুলি অবিরত থাকবে।

আপনি সময়টির আউটপুটটি / dev / নালকে নল দিয়ে যাবেন এবং এটি আপনার বিদ্যমান প্রক্রিয়াটির কোনও প্রধান পুনর্লিখন ছাড়া আপনি যা খুঁজছেন ঠিক তা করবে।

আমি ভাবছি যদি আমি এক মুহুর্তের জন্য চিন্তা করি তবে আমি '/ usr / bin / সময়' এর স্ট্যাডার বকবক না করে একই কাজ করতে অন্য একটি প্রোগ্রাম নিয়ে আসতে পারি। অথবা এমনকি একটি নিজে লিখুন, এটি কেবল একটি 'কাঁটাচামচ' (বা এক্সিকিউটিভ () ডেরিভেটিভ)।

'/ Usr / বিন / সময়' ব্যবহার করা মনে রাখবেন, কারণ আমি নিশ্চিত নই যে বাশের অন্তর্নির্মিত 'সময়' সিগন্যালের একই 'খাওয়া' করবে।


1
timeএই উদ্দেশ্যে একটি ভাল বিকল্প হতে পারে env, যেহেতু এটি যা করে তা হ'ল প্রোগ্রামটি চালিত পরিবেশের পরিবেশে শূন্য বা আরও বেশি alচ্ছিক পরিবর্তনশীল যুক্ত করে। এটি নিজস্ব কোনও আউটপুট নির্গত করে না এবং অনুরোধ করা প্রোগ্রামের রিটার্ন কোডটি যাকেই ডাকা হবে তা ফিরে দেওয়া হবে env
জেমস স্নেরিংগার

Uck চাকল} আমি এটি লেখার কিছুক্ষণ পরে ভাবলাম। সময়টি প্রথম জিনিস ছিল যা "রান কিছু" কমান্ড হিসাবে মনে আসে। যদিও ভাল কাজ করে। অভিনন্দন এবং ধন্যবাদ।
লার্নিক্স

2

আমার পক্ষে timeবা তাদের পক্ষে envকাজ করেনি (তারা তাদের সন্তানের প্রোগ্রামের রিটার্ন মানটি দিয়ে যায়) তাই আমি লিখেছিলাম bliss:

#!/bin/sh
"$@"
exit 0

তারপর chmod u+x ~/bliss

এবং কিছু find_or_similar | xargs ~/bliss fatally_dying_program.sh

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