استفاده از xargs در ترکیب با bash -c برای ایجاد دستورات پیچیده – CloudSavvy IT


Shutterstock / ksb

xargs آتش بازی برای دستورات پوسته شما است. هر خروجی تولید شده توسط هر دستور پوسته را می توان به xargs ارسال کرد تا در یک خط فرمان دیگر بیشتر پردازش شود. یاد بگیرید امروز از این قدرت عالی xargs استفاده کنید!

xargs مقدمه

همکار من دیو مک کی مقاله جالبی در مورد نحوه استفاده از دستور xargs در لینوکس نوشت ، که ممکن است بخواهید ابتدا آن را بخوانید تا به طور کامل مقدمه و مطالعه xargs را بخوانید.

این مقاله بر روی یک مشکل خاص متمرکز خواهد شد: وقتی با محدودیت های لوله گذاری سنتی یا طبیعی روبرو می شوید چه کاری باید انجام دهید (; از هم جدا شده) سفارش دستورات لینوکس و وقتی حتی به نظر نمی رسد استفاده از xargs جواب فوری بدهد؟

این حالت به طور منظم ، اگر نه غالباً ، هنگام نوشتن اسکریپت های تک خطی در خط فرمان و / یا هنگام پردازش داده های پیچیده یا ساختارهای داده ، وجود دارد. اطلاعات ارائه شده در اینجا مبتنی بر تحقیق و تجربه چندین ساله استفاده از این روش و رویکرد خاص است.

شیپورها و قیچی ها

هر کسی که Bash را یاد بگیرد با گذشت زمان مهارت نوشتن خط فرمان خود را توسعه می دهد. نکته جالب در مورد Bash این است که تمام مهارت های آموخته شده در خط فرمان به راحتی به اسکریپت های Bash ترجمه می شوند (که معمولاً با .sh افزونه). نحو یکسان است.

و با پیشرفت مهارت ها ، مهندسان جدیدتر معمولاً اصطلاح لوله را پیدا می کنند. استفاده از یک لوله آسان و ساده است: خروجی از دستور قبلی برای ورودی بعدی به ورودی “منتقل می شود” ، آن را مانند یک خط لوله تصور کنید که آب را از یک منبع خروجی به یک منبع ورودی در جای دیگر منتقل می کند ، مانند آب از یک سد لوله به یک توربین آب.

بیایید به یک مثال آسان نگاه کنیم:

echo 'a' | sed 's/a/b/'

یک مثال ساده از لوله Bash با جایگزینی متن برای عبارات منظم

در اینجا ما فقط “a” را تکرار کردیم و متعاقباً با کمک ویرایشگر جریان متن همان را تغییر دادیم و. خروجی به طور طبیعی “b” است: sed جایگزین (s فرمان) “a” با “b” می شود.

مدتی بعد ، مهندس متوجه خواهد شد که لوله ها هنوز فقط دارای قابلیت های محدودی هستند ، خصوصاً وقتی کسی بخواهد داده ها را در قالب آماده شده برای ابزار بعدی پیش پردازش کند. به عنوان مثال ، این وضعیت را در نظر بگیرید:

مواجهه با چالش ها با کمک یک لوله در ترکیب با کشتن

در اینجا ما شروع به خوابیدن در پس زمینه می کنیم. سپس ما استفاده می کنیم pidof تا PID دستور خواب اجرایی را بازیابی کرده و سعی کنید آن را با استفاده از آن بکشید kill -9 (9-را به عنوان فرآیند تخریب فرآیند مخرب در نظر بگیرید). شکست می خورد. سپس هنگام شروع فرایند پس زمینه سعی می کنیم از PID ارائه شده توسط پوسته استفاده کنیم ، اما این نیز ناموفق است.

مشکل این است kill ورودی را مستقیماً نمی پذیرد ، خواه از آنجا وارد شود ps یا حتی از ساده echo. برای حل این مشکل می توانیم با استفاده از xargs خروجی را از یا ps یا echo فرمان) و آنها را به عنوان ورودی به آنها ارائه دهید kill، آنها را با دستور kill بحث می کند. گویی اینگونه اعدام کرده ایم kill -9 some_pid به طور مستقیم. بیایید ببینیم این چگونه کار می کند:

sleep 300 &
pidof sleep | xargs kill -9

xargs با دستور kill tub که قبلاً مشاهده شد ، مشکل را حل می کند

این کاملاً کار می کند و به آنچه ما در نظر داریم انجام می دهد: کشتن روند خواب. یک تغییر کوچک در کد (یعنی فقط xargs به دستور اضافه کنید) ، اما یک تغییر بزرگ در مفید بودن Bash برای توسعه دهنده!

ما همچنین می توانیم استفاده کنیم -I گزینه (تعریف آرگومان جایگزین رشته) از kill تا کمی شفاف تر شود که ما چگونه استدلال هایی را برای کشتن ارائه می دهیم: i12b در اینجا ما تعریف می کنیم {} به عنوان رشته جایگزین ما به عبارت دیگر ، xargs چه زمانی می بیند {}، جایگزین خواهد شد {} به هر چیزی که توسط آخرین دستور وارد شده است.

و با این حال ، حتی این نیز محدودیت هایی دارد. اگر بخواهیم اطلاعات اشکال زدایی خوبی را که درجا و داخل بیانیه چاپ شده اند ارائه دهیم ، چه می کنیم؟ در حال حاضر ، غیرممکن به نظر می رسد.

بله ، می توانیم خروجی را با a پردازش کنیم sed بیان منظم یا قرار دادن زیر پوشش ($()) در جایی وجود دارد ، اما به نظر می رسد که همه آنها هنوز محدودیت هایی دارند ، به ویژه هنگامی که زمان ساخت جریانهای داده پیچیده بدون استفاده از دستور جدید و بدون استفاده از پرونده های موقتی میانه است

چه می شود اگر می توانستیم – یک بار برای همیشه – این محدودیت ها را پشت سر بگذاریم و در ایجاد 100٪ آزاد باشیم همه جوره خط فرمان Bash که ما دوست داریم ، فقط با استفاده از لوله ها ، xargs و پوسته Bash ، هیچ پرونده میانی موقت و هیچ دستور جدیدی در حال اجرا نیست؟ ممکن است.

و اگر کسی به شما نشان دهد ، اصلاً پیچیده نیست ، اما برای اولین بار فهمیدن آن به کمی زمان و بحث نیاز داشت. من مخصوصاً می خواهم از مربی سابق لینوکس و همکار سابقم اندرو دالگلیش تشکر و تشکر کنم – با هم ما یاد گرفتیم که چطور بهتر این کار را انجام دهیم کمی کمتر از 10 سال پیش.

به xargs With bash -c خوش آمدید

همانطور که دیدیم ، حتی هنگامی که از لوله ها به همراه xargs استفاده می شود ، باز هم برای اسکریپت های کمی قدیمی تر در سطح مهندس با محدودیت هایی روبرو خواهیم شد. بیایید مثال قبلی خود را بیاوریم و اطلاعات اشکال زدایی را بدون پردازش نتیجه پس از آن تزریق کنیم. دستیابی به این امر معمولاً دشوار است ، اما اینگونه نیست xargs همراه با bash -c:

sleep 300 &
pidof sleep | xargs -I{} echo "echo 'The PID of your sleep process was: {}'; kill -9 {}; echo 'PID {} has now been terminated'" | xargs -I{} bash -c "{}"

دنباله ای پیچیده برای ساختن دستور xargs و استفاده از bash -c

ما در اینجا از دو مورد استفاده کردیم xargs دستورات اولی یک خط فرمان سفارشی ایجاد می کند و از خروجی دستور قبلی در لوله (موجود) به عنوان ورودی استفاده می کند pidof sleep) و دستور xargs دوم این دستور تولید شده ، ورودی سفارشی (مهم!) را اجرا می کند.

چرا ورود سفارشی؟ دلیل این امر این است که xargs پیش فرض خط به خط از طریق ورودی خود پردازش می کند (خروجی دستور قبلی در لوله) و آنچه را که به آنها دستور داده شده است برای هر خط ورودی انجام شود ، اجرا می کند.

اینجا قدرت زیادی وجود دارد. این بدان معناست که شما می توانید هر دستور سفارشی را ایجاد و بسازید و سپس آن را اجرا کنید ، بدون توجه به فرمت داده های ورودی ، کاملاً بدون نگرانی در مورد نحوه اجرای آن. تنها نحوی که باید به یاد داشته باشید عبارت زیر است:

some_command | xargs -I{} echo "echo '...{}...'; more_commands; more_commands_with_or_without{}" | xargs -I{} bash -c "{}"

به خاطر داشته باشید که ورودی echo (اکو دوم) فقط درصورت نیاز به این است که بخواهید متن واقعی را دوباره نمایش دهید. در غیر این صورت ، اگر دوم echo اول نبود echo نمایش “PID …” و غیره را شروع می کند و bash -c زیر پوسته نمی تواند این را به عنوان یک دستورالعمل تجزیه و تحلیل کند (IOW ، “PID …” یک دستور نیست و به همین ترتیب قابل اجرا نیست ، از این رو پژواک ثانویه / تو در تو).

یک بار به یاد می آورید bash -c، -I{} و روش انعکاس از پژواک دیگر (و در صورت لزوم می توان از توالی های تخلیه استفاده کرد) ، متوجه خواهید شد که از این نحو بارها و بارها استفاده می کنید.

بیایید بگوییم شما باید سه کار را روی یک فایل در فهرست انجام دهید: 1) نمایش محتوای فایل ، 2) انتقال آن به یک زیر شاخه ، 3) حذف آن. این کار معمولاً به یک سری مراحل با دستورالعمل های گام به گام مختلف نیاز دارد و در صورت پیچیدگی بیشتر ، حتی ممکن است به پرونده های موقتی نیاز داشته باشید. اما انجام این کار با کمک بسیار آسان است bash -c و xargs:

echo '1' > a
echo '2' > b
echo '3' > c
mkdir subdir
ls --color=never | grep -v subdir | xargs -I{} echo "cat {}; mv {} subdir; rm subdir/{}" | xargs -I{} bash -c "{}"

مینی اسکریپت کاملاً مبتنی بر xargs و bash -c را در یک فرمان تک خطی کار کنید

ابتدا سریعاً یادآوری کنید که استفاده از آن همیشه ایده خوبی است --color=never برای lsبرای جلوگیری از مشکلات سیستم که از کدگذاری رنگ برای خروجی لیست فهرست استفاده می کند (به طور پیش فرض در اوبونتو گنجانده شده است) ، زیرا این اغلب باعث تجزیه و تحلیل شدید می شود زیرا کدهای رنگ در واقع به ترمینال ارسال می شوند و دارای پیشوند هستند به ورودی های لیست دایرکتوری.

ابتدا سه فایل a ، b و c و زیر شاخه به نام subdir ایجاد می کنیم. ما این زیر شاخه را از لیست دایرکتوری هایی که دارای آنها هستند حذف می کنیم grep -v پس از مشاهده اینکه یک تست آزمایشی سریع انجام می شود (بدون اجرای دستور یا به عبارت دیگر هیچ xargs دوم) زیرشاخه همچنان نمایش داده می شود.

همیشه مهم است که ابتدا دستورات پیچیده خود را آزمایش کنید ، قبل از انتقال واقعی آنها به bash subhell ، خروجی را مشاهده کنید bash -c برای اعدام.

سرانجام ، ما دقیقاً از همان روشی که قبلاً برای ساخت یا فرمان دیده شد استفاده می کنیم. cat (نمایش) پرونده ، انتقال پرونده (نشان داده شده توسط {}) به زیر شاخه و در نهایت پرونده داخل زیر شاخه را حذف کنید. می بینیم که محتویات 3 پرونده (1 ، 2 ، 3) بر روی صفحه نمایش داده می شود و اگر فهرست فعلی را بررسی کنیم ، پرونده های ما از بین می روند. همچنین می توانیم ببینیم که دیگر هیچ پرونده ای در زیر شاخه وجود ندارد. همه آنها خوب کار می کنند.

خلاصه کردن

استفاده كردن xargs به عنوان یک نیروی عالی برای کاربر پیشرفته لینوکس (و در این مورد) Bash. استفاده كردن xargs در ترکیب با bash -c هنوز هم قدرت بسیار بیشتری را حمل می کند. توانایی منحصر به فرد در ساخت 100٪ رایگان خطوط فرمان سفارشی و پیچیده بدون نیاز به پرونده ها یا سازه های میانی و بدون نیاز به دستورات ترتیب داده شده / ترتیب دار.

لذت بردن!


منبع: khabar-mehman.ir

دیدگاهتان را بنویسید

Comment
Name*
Mail*
Website*