انجمنهای فارسی اوبونتو
کمک و پشتیبانی => راهنماها، نکات و ترفندها => نویسنده: سید وحید رضا برهانی در 04 شهریور 1397، 08:12 بظ
-
سلام
دستورات زیر رو در نظر بگیرید:
function f()
> {
> echo $#
> }
x="1 2"
توی بش وقتی f x رو اجرا می کنید خروجی ۲ هست یعنی بش x رو به عنوان دوتا پارامتر می فرسته به f.
ولی اگر توی zsh اجرا کنید خروجی ۱ هست یعنی zsh به عنوان یک پارامتر می فرسته.
حالا چطوری باید از zsh استفاده کنم که مثل بش رفتار کنه؟
-
سلام
در zsh به صورت پیش فرض تقسیم کلمات با space اتفاق نمیوفته. برای اینکه تقسیم کلمات با فاصله رو در zsh فعال کنین می تونین از راه های زیر استفاده کنین :
1.فعال کردن آپشن shwordsplit
اینجا مشابه bash تقسیم کلمات با فاصله اتفاق میوفته :
setopt shwordsplit
function f() {echo $#}
x="1 2"
f $x
2.راه دیگه استفاده از ${=x} به جای $x موقع فراخوانی تابع هستش (این ساختار آپشن shwordsplit رو فقط برای متغیر دلخواه فعال می کنه):
function f() {echo $#}
x="1 2"
f ${=x}
3.راه دیگه استفاده از آرایه به جای رشته هستش :
function f() {echo $#}
x=(1 2)
f $x
4.و راه آخر استفاده از دستور eval هستش :
function f() {echo $#}
x="1 2"
eval f $x
دلیل فعال نبودن این قابلیت هم طبق داکیومنت های خود zsh این هستش که آرایه ها کارایی بیشتری نسبت به رشته ها دارن و همین قضیه باعث شده تا توسعه دهنده های zsh ترجیح بدن این قابلیت به صورت پیش فرض غیرفعال باشه و هر کسی بخواد چنین کاری انجام بده از آرایه ها استفاده کنه نه از رشته ها.
-
ممنون :)
ظاهرا فقط با eval می شه یک کدی رو نوشت که توی بش و zsh یکسان اجرا بشه.
-
ممنون :)
ظاهرا فقط با eval می شه یک کدی رو نوشت که توی بش و zsh یکسان اجرا بشه.
خواهش می کنم.
بله البته بستگی به کدی هم داره که می خواید بزنید ؛ در کل راه زیاده مثلاً شما می تونین اسکریپتتون روی طوری بنویسین که اول شل رو چک کنه و اگه zsh بودش setopt shwordsplit رو به اجرا در بیاره.
if [[ -n $(readlink "/proc/$$/exe" | grep 'zsh') ]]; then
setopt shwordsplit
fi
function f() { echo $#; }
x="1 2"
f $x
پ.ن : در عبارت بالا استفاده از $SHELL به جای /proc/$$/exe درست نیست، چون $SHELL تنها environment variable مربوط به SHELL رو نیشون می ده نه شلی که با اون اسکریپت اجرا می شه.
ولی می تونین از دستوری مثل دستور زیر هم به جای /proc/$$/exe استفاده کنین :
if [[ $(ps -p $$ -ocomm=) = "zsh" ]]; then