|| و &&
command1 && command2این دستور command1 را اجرا میکند و اگر خروجی صفر بود (درست) command2 اجرا میشود
[ -f fileName ] && ./fileNameاین قطعه کد (که خیلی استفاده میشه) یعنی اگر فایل fileName وجود داشت آنرا اجرا کن در غیر این صورت کاری انجام نمیدهد
* اگر بخواهیم چند کار انجام دهیم آنها رو با {} احاطه میکنیم
|| برعکس && هست یعنی اگر خروجی command1 غیر صفر بود command2 اجرا میشود
Redirecting
توی shell سه نوع ورودی/خروجی داریم:
۰ - ورودی از keyboard اسم:standard input
۱ - خروجی به console اسم:standard output
۳ - خروجی به console برای خطاها اسم: standard error
× برای توضیح بگم که stderr با stdout هیچ فرقی نداره و فقط برای جداسازی این دوتا هست
[n]> file
خروجی استاندارد یا شماره n را در file میریزد
[n]>> file
خروجی استاندارد یا شماره n را در انتهای file میریزد و آنرا پاک نمیکند
[n]< file
ورودی استاندارد یا شماره n را از file میخواند
[n]<> file
فایل file را برای ورودی و خروجی استاندارد یا n باز میکند
[n1]>&n2
خروجی استاندارد یا شماره n1 را به n2 میفرستد
[n1]<&n2
ورودی استاندارد یا شماره n1 را به n2 میفرستد
[n]<&-
ورودی استاندارد یا n را میبندد
[n]>&-
خروجی استاندارد یا n را میبندد
[n]<< endWord
write here
and here
endWord
هرچه بین دو تا endWord نوشته شده باشه رو به ورودی استاندارد یا n میفرستد
اگر میخواهید از دستور cmd هیچ خروجی روی تصویر نشان داده نشود:
cmd 2>&1 >/dev/null* /dev/null مثل یک سطل آشغال هست هرچی توش بریزین به هیچ جایی نمیره
پایپ
فرض کنیم میخواهیم اسم فایلهای یک دیرکتوری را با ls بگیریم و با sort مرتب کنیم
ls > temp
sort < tempبه جای استفاده از فایل واسطه میتوانیم مستقیما از خروجی یک دستور خوانده و به ورودی دیگری بدیم با یه پایپ (لوله)!
ls | sortتوابع و پارامترها
توی shell توابع یک نوع برنامه هست و بلعکس!
برای همین همهی مطالب این قسمت (به جز تعریف تابع) برای یک script بدون تابع هم (که خودش یک برنامه است) برقرار است
تعریف تابع
FunctionName()
{
commands
.
.
.
return exitStatus
}exitStatus یک عدد صحیح است که به هنوان خروجی در نظر گرفته میشود
صدازدن تابع
از اون جایی تابع همون برنامهس از همون syntax استفاده میکنیم
func param1 param2و کد خروجی هم (از اونجایی که یه برنامه هست

) توی متغییر ?$ ذخیره میشه
برای کسانی که نمیدونن هم بگم هر برنامه یه کد خروجی داره که توی ? ذخیره میشه که معمولا نشان دهندهی اینه که برنامه درست اجرا شده یا نه:
arman:~$ ls /
bin cdrom etc initrd lib media opt root srv tmp var
boot dev home initrd.img lost+found mnt proc sbin sys usr vmlinuz
arman:~$ echo $?
0
arman:~$ ls /err
ls: /err: No such file or directory
arman:~$ echo $?
2
برای اینکه کد خروج کل shell script رو معین کنیم یا از کل برنامه خارج شویم از تابع exit استفاده میکنیم
مثلا
exit 2پارامترها
پارامتر اول توی 1$، پارامتر دوم توی 2$، ... و پارامتر صفرم توی 0$ ذخیره میشه
test.sh:
#!/bin/sh
echo "0 = $0 1 = $1 2 = $2"
arman:~$ ./test.sh hello world
0 = ./test.sh 1 = hello 2 = worldپارامترهای خاص
پارامتر صفرم (0$) همون اسم برنامه هست (به همون طریقی که اجرا شده)
متغییر #$ تعداد پارامترها را مشخص میکنه
متغییر @$ شامل تمام متغییرها است که وقتی به string تبدیل میشود پارامترها را جداگانه مشخص میکند
متغییر *$ شامل تمام متغییرها است که وقتی به string تبدیل میشود پارامترها به هم میچسبند و بین آنها اولین کاراکتر متغییر IFS هست (که معمولا space هست)
متغییر $$ شماره پروسه shell جاری هست
متغییر !$ شماره پروسه آخرین دستور background یا آخرین پایپ است
ابن مثال خیلی واضح تر از بالاست

test.sh:
#!/bin/sh
echo "0 = $0"
echo "# = $#"
echo "@ = $@"
for a in "$@"; do
echo $a
done
IFS="/"
echo "* = $*"
for a in "$*"; do
echo $a
done
echo "\$ = $$"
arman:~$ ./test.sh "hello world" hello2 world2
0 = ./test.sh
# = 3
@ = hello world hello2 world2
hello world
hello2
world2
* = hello world/hello2/world2
hello world hello2 world2
$ = 19750