در دنیای یونیکس، قدرت واقعی زمانی آشکار میشود که بتوانید ابزارهای ساده را بهصورت ترکیبی و زنجیرهای به کار بگیرید تا کارهای پیچیده را انجام دهید. این فصل به سه مفهوم کلیدی در ترکیب دستورات میپردازد: xargs برای ساخت و اجرای دستورات از روی ورودی، tee برای انشعاب جریان داده، و استراتژیهای پیشرفتهتر برای ترکیب دستورات با Pipeها.
xargs (Execute Arguments)
دستور xargs (مخفف X ARGument Standard) یکی از قدرتمندترین و در عین حال ظریفترین ابزارهای خط فرمان است. وظیفهی اصلی xargs این است که ورودی استاندارد (stdin) را بگیرد، آن را به بخشهایی (آرگومانها) تقسیم کند و این آرگومانها را بهعنوان پارامتر به یک دستور دیگر بدهد و آن را اجرا کند.
در بسیاری از موارد، دستورات خروجی خود را بهصورت خط به خط (یا با فاصله) تولید میکنند، اما دستور دیگری ممکن است نتواند این ورودی را مستقیماً از stdin بخواند و نیاز به آرگومان در خط فرمان داشته باشد. xargs این شکاف را پر میکند.
ساختار کلی:
command1 | xargs [option] command2
نحوهی کار xargs
xargs ورودی خود را از stdin میخواند، آن را به آرگومانهای جداگانه تبدیل میکند (بهطور پیشفرض بر اساس فاصله یا خط جدید) و سپس دستور مشخصشده را با آن آرگومانها اجرا میکند.
مثال ساده:
echo "file1 file2 file3" | xargs rm
این دستور معادل اجرای rm file1 file2 file3 است.
گزینههای اصلی xargs
| گزینه | توضیح | مثال |
|---|---|---|
-n n | تعداد آرگومانهای ارسالی به هر بار اجرا. | xargs -n 1 echo (هر بار یک آرگومان) |
-d delim | تعیین جداکنندهی دلخواه (بهجای فاصله و خط جدید). | xargs -d ',' echo (جداکننده: کاما) |
-0 | استفاده از کاراکتر null (\0) بهعنوان جداکننده (برای find -print0). | find . -name "*.txt" -print0 | xargs -0 rm |
-I {} | جایگزینی آرگومانها در یک الگوی مشخص. | xargs -I {} cp {} /backup/ |
-p | درخواست تأیید قبل از هر اجرا (Prompt). | xargs -p rm |
-t | نمایش دستور قبل از اجرا (Trace). | xargs -t rm |
-P n | اجرای همزمان (Parallel) با n فرآیند. | xargs -P 4 (۴ فرآیند همزمان) |
--max-args=n | معادل -n (حداکثر آرگومان در هر بار). | xargs --max-args=3 echo |
--max-procs=n | معادل -P (حداکثر فرآیندهای همزمان). | xargs --max-procs=2 |
--max-chars=n | محدودیت تعداد کاراکترهای خط فرمان. | xargs --max-chars=1000 |
مثالهای پایه
-
حذف همهی فایلهای
.tmp:find . -name "*.tmp" | xargs rm
(معادل
rmکردن تمام فایلهای پیدا شده) -
ایجاد دایرکتوریهای لیست شده در یک فایل:
cat dirs.txt | xargs mkdir
dirs.txtشامل نام دایرکتوریهاست. -
استفاده از
xargsباechoبرای نمایش آرگومانها:echo "one two three" | xargs echo # خروجی: one two three
-
محدود کردن تعداد آرگومانها در هر بار (با
-n):echo "1 2 3 4 5 6" | xargs -n 2 echo # خروجی: # 1 2 # 3 4 # 5 6
این قابلیت زمانی مفید است که دستور شما نمیتواند تعداد زیادی آرگومان را یکجا بپذیرد.
-
جایگزینی آرگومانها در یک دستور با
-I:echo "file1 file2" | xargs -I {} cp {} /backup/
{}بهعنوان جایگزین برای هر آرگومان عمل میکند. این دستور معادلcp file1 /backup/و سپسcp file2 /backup/است. -
استفاده از
xargsبرای اجرای دستورات با تأیید (با-p):find . -name "*.log" | xargs -p rm
قبل از هر بار اجرای
rm، از شما تأیید میخواهد. -
نمایش دستور در حال اجرا (با
-t):echo "file1 file2" | xargs -t rm # خروجی: rm file1 file2
۱. xargs و find: ترکیبی قدرتمند
یکی از رایجترین کاربردهای xargs، ترکیب آن با find برای اجرای دستورات بر روی فایلهای پیدا شده است.
مثالها:
-
حذف فایلهای
*.tmpبا مدیریت نامهای دارای فاصله:find . -name "*.tmp" -print0 | xargs -0 rm
-
-print0: فایلها را با کاراکتر null جدا میکند (بهجای خط جدید). -
-0:xargsرا با جداکنندهی null تنظیم میکند.
این روش برای فایلهایی که نام آنها شامل فاصله یا کاراکترهای خاص است، ضروری است.
-
-
تغییر مجوزهای فایلها:
find . -type f -name "*.sh" -print0 | xargs -0 chmod +x
تمام فایلهای
.shرا اجرایی میکند. -
جستجوی یک متن در فایلها (با
grep):find . -name "*.py" -print0 | xargs -0 grep "TODO"
-
استخراج محتوای فایلهای فشرده:
find . -name "*.zip" -print0 | xargs -0 -I {} unzip {} -d /extracted/
-
کپی فایلها به یک دایرکتوری خاص (با
-I):find . -name "*.pdf" -print0 | xargs -0 -I {} cp {} ~/Documents/
۲. xargs در ترکیب با grep و sed
xargs میتواند خروجی grep را به دستورات دیگری مانند sed و awk بدهد تا تغییرات گستردهای روی فایلها اعمال شود.
مثالها:
-
جایگزینی یک متن در تمام فایلهای
.txt:grep -l "old_text" *.txt | xargs sed -i 's/old_text/new_text/g'
-
grep -l: فقط نام فایلهای حاویold_textرا نمایش میدهد. -
xargs: این نامها را بهsed -iمیدهد تا جایگزینی را انجام دهد.
-
-
حذف خطوط خالی از تمام فایلهای
.log:find . -name "*.log" | xargs sed -i '/^$/d'
۳. xargs با -P برای اجرای موازی
گزینهی -P به xargs اجازه میدهد که چندین فرآیند را بهصورت همزمان (Parallel) اجرا کند. این قابلیت برای پردازش حجم عظیم داده و افزایش سرعت بسیار مفید است.
مثالها:
-
فشردهسازی همزمان چند فایل (با
gzip):ls *.log | xargs -P 4 -I {} gzip {}
۴ فایل بهصورت همزمان فشرده میشوند.
-
دانلود همزمان چند فایل (با
wget):cat urls.txt | xargs -P 4 -I {} wget {}
۴ دانلود بهصورت همزمان انجام میشود.
-
پردازش همزمان فایلها (با یک اسکریپت):
find . -name "*.data" | xargs -P 2 -I {} ./process.sh {}
tee (بازبینی در این بخش)
دستور tee (که پیشتر در بخش Redirection معرفی شد) برای انشعاب (Branching) جریان داده استفاده میشود. به عبارت دیگر، tee ورودی خود را هم به خروجی استاندارد (stdout) میفرستد و هم در یک یا چند فایل مینویسد.
ساختار کلی:
command | tee [option] [file...]
گزینههای اصلی tee
| گزینه | توضیح |
|---|---|
-a | (Append) به انتهای فایل اضافه میکند (بهجای بازنویسی). |
مثالها
-
ذخیرهی خروجی
lsدر یک فایل و مشاهدهی آن روی صفحه:ls -la | tee filelist.txt
خروجی هم روی صفحه دیده میشود و هم در
filelist.txtذخیره میشود. -
نوشتن در چند فایل بهطور همزمان:
echo "Hello World" | tee file1.txt file2.txt file3.txt
-
افزودن به یک فایل (با
-a):echo "New line" | tee -a log.txt
-
استفاده با
sudoبرای نوشتن در فایلهای محافظتشده:echo "new_config" | sudo tee /etc/myapp/config.conf
این روش استاندارد و امنتر از
sudo echo >است. -
ذخیرهی خروجی و خطاها با استفاده از
tee(با2>&1):command 2>&1 | tee output.log
-
ذخیرهی خروجی در یک فایل و ارسال به دستور بعدی (Pipeline):
dmesg | tee kernel.log | grep "error"
خروجی
dmesgهم درkernel.logذخیره میشود، هم بهgrepفرستاده میشود.
Combining Commands with Pipes
استفاده از Pipeها (|) برای ترکیب دستورات، قلب فلسفهی یونیکس است. با ترکیب xargs و tee با سایر ابزارها، میتوانید گردشهای کاری بسیار قدرتمندی ایجاد کنید.
۱. الگوی استاندارد: command1 | command2 | command3
این الگوی ساده و پرکاربرد، خروجی دستور اول را به دستور دوم و خروجی دستور دوم را به دستور سوم میدهد.
مثال:
ps aux | grep "python" | awk '{ print $2 }' | xargs kill -9
-
ps aux: لیست فرآیندها. -
grep "python": فیلتر فرآیندهای پایتون. -
awk '{ print $2 }': استخراج PIDها. -
xargs kill -9: کشتن همهی فرآیندهای پایتون.
۲. الگوی ذخیرهسازی میانی با tee
زمانی که میخواهید خروجی یک مرحله را هم ذخیره کنید و هم به مرحلهی بعد بفرستید، از tee استفاده کنید.
مثال:
cat log.txt | tee raw.log | grep "ERROR" | tee errors.log | awk '{ print $1 }' > ip_list.txt
-
cat log.txt: خواندن لاگ. -
tee raw.log: ذخیرهی نسخهی کامل. -
grep "ERROR": فیلتر خطاها. -
tee errors.log: ذخیرهی خطاها. -
awk '{ print $1 }': استخراج آیپیها (فیلد اول). -
> ip_list.txt: ذخیرهی آیپیها.
۳. الگوی find | xargs برای پردازش فایلها
این یکی از رایجترین و قدرتمندترین ترکیبها در سیستمهای یونیکس است.
مثالها:
-
پیدا کردن و حذف فایلهای قدیمی (بیش از ۳۰ روز):
find /var/log -name "*.log" -mtime +30 -print0 | xargs -0 rm
-
پیدا کردن فایلهای بزرگ و نمایش آنها بهصورت مرتب:
find . -type f -exec du -h {} + | sort -hr | head -10
(این روش از
xargsاستفاده نمیکند، اما ترکیبfindوduوsortرا نشان میدهد) -
جستجو و جایگزینی در چند فایل بهصورت ایمن (با ساخت بکاپ):
grep -l "old" *.txt | xargs -I {} sed -i.bak 's/old/new/g' {}
-
پیدا کردن فایلهای حاوی یک متن و نمایش آنها با
less(صفحهبهصفحه):find . -name "*.py" -print0 | xargs -0 grep -l "TODO" | xargs less
۴. الگوی cat | ... | xargs برای تولید دستورات
مثال:
cat urls.txt | xargs -I {} echo "wget -O output_{}.html {}" |
-
cat urls.txt: خواندن لیست URLها. -
xargs -I {} echo "...": ساخت دستوراتwget. -
bash: اجرای دستورات ساخته شده.
استراتژیهای پیشرفتهی ترکیب دستورات
۱. استفاده از && و || در کنار xargs
میتوانید با xargs -I {} دستورات شرطی بسازید:
find . -name "*.sh" -print0 | xargs -0 -I {} sh -c 'chmod +x "{}" && echo "Made executable: {}"'
۲. استفاده از xargs با -n برای پردازش دستهای
زمانی که دستور شما نمیتواند همهی آرگومانها را یکجا بپذیرد (مثلاً به دلیل محدودیت طول خط فرمان)، از -n استفاده کنید:
ls *.jpg | xargs -n 10 convert -resize 800x600 {} thumbnails/
هر بار ۱۰ فایل را پردازش میکند.
۳. ترکیب tee با xargs برای نظارت و پردازش
tail -f log.txt | tee /dev/tty | grep "ERROR" | xargs -I {} echo "ALERT: {}" >> alerts.txt
-
tail -f: دنبال کردن لاگ. -
tee /dev/tty: نمایش همزمان روی صفحه. -
grep "ERROR": فیلتر خطاها. -
xargs: ساخت هشدار و ذخیره درalerts.txt.
۴. استفاده از xargs برای موازیسازی پردازش دادهها
seq 1 100 | xargs -P 10 -I {} echo "Processing {}", {}
۱۰ فرآیند همزمان، اعداد ۱ تا ۱۰۰ را پردازش میکنند.
خلاصه و نکات کلیدی
-
xargsبرای تبدیل stdin به آرگومانهای خط فرمان استفاده میشود. برای کار با فایلهایی که نام آنها شامل فاصله است، حتماً از-print0و-0استفاده کنید. -
teeبرای انشعاب جریان داده (نمایش و ذخیرهسازی همزمان) استفاده میشود. برای نوشتن در فایلهای محافظتشده، آن را باsudoاجرا کنید. -
ترکیب
find | xargsیکی از قدرتمندترین الگوها برای پردازش دستهجمعی فایلهاست. -
استفاده از
-Pدرxargsبرای افزایش سرعت با اجرای موازی بسیار مفید است. -
ترتیب و نوع جداکنندهها در
xargsبسیار مهم است. همیشه از-0باfind -print0استفاده کنید تا از مشکلات نام فایلها با فاصله جلوگیری کنید. -
xargsیک ابزار کممصرف و بسیار سریع است که در مقایسه با حلقههایwhileدر shell، کارایی بسیار بالاتری دارد.
مقایسهی xargs با حلقههای while
گاهی میتوان بهجای xargs از حلقههای while استفاده کرد:
# با xargs find . -name "*.txt" | xargs -I {} cp {} /backup/ # با while find . -name "*.txt" | while read file; do cp "$file" /backup/; done
| ویژگی | xargs | حلقهی while |
|---|---|---|
| سرعت | بسیار سریعتر (یک بار فراخوانی) | کندتر (هر بار یک فراخوانی) |
| مدیریت نام فایلها | نیاز به -0 برای فایلهای دارای فاصله | با IFS= و -r بهخوبی مدیریت میشود |
| پیچیدگی دستورات | محدود (یک دستور ساده) | انعطافپذیر (میتوان چندین دستور اجرا کرد) |
| موازیسازی | بله (-P) | خیر (میتوان با & شبیهسازی کرد) |
برای دستورات ساده، xargs بسیار سریعتر است. برای منطق پیچیده، حلقهی while مناسبتر است.