التعامل مع المعلمات في sh
سؤال
أنا أعمل مع فائدة (انسجام, ، ولكن هذه ليست النقطة) التي تقبل المعلمات مثل:
$ unison -path path1 -path path2 -path path3
أرغب في كتابة نص SH الذي يمكنني تشغيله مثل هذا:
$ myscript path1 path2 path3
آمل أن يكون حل متوافق بوقيا، لكن باش محددة سيكون جيدا أيضا.
أنا أظن أنه يجب أن يكون شيء مثل:
#!/bin/sh
unison ${*/ / -path }
ولكن هذا لا يعمل.
تعديل: حسنا، أعتقد أنني حصلت على شيء:
#!/bin/bash
PARAMS=
for arg in "$@"
do
PARAMS+=" -path '$arg'"
done
unison $PARAMS
المشاكل هي هذه تعمل فقط في باش، وأنا متأكد من أن هناك طريقة أفضل للاقتباس المعلمات.
المحلول
لم يتم التحقق منه، فقد يكون بسيطة مثل:
exec unison -path $1 -path $2 -path $3
إذا لم تقم بتضمين مسافات في أسماء المسار الخاص بك، فيمكنك التعامل مع عدد متغير من الوسائط مع:
arglist=""
for path in "$@"
do
arglist="$arglist -path $path"
done
exec unison $arglist
إذا كان لديك مسافات في أسماء المسار الخاص بك، فعليك أن تعمل أكثر صعوبة؛ عادة ما أستخدم برنامج مخصص يسمى escape
, ، والتي يقتبس الحجج التي تحتاج إلى اقتباس، و eval
:
arglist=""
for path in "$@"
do
path=$(escape "$path")
arglist="$arglist -path $path"
done
eval exec unison "$arglist"
لاحظ أن استخدام Perl أو Python سيجعل حجج معالجة مع المساحات فيها أسهل - لكن السؤال يسأل عن Shell.
قد يكون ذلك ممكنا أيضا في BASH لاستخدام متغير صفيف Shell - قم ببناء الحجج في صفيف وتمرير الصفيف كحجج إلى unison
أمر.
نصائح أخرى
إذا كنت تستخدم صفائف Bash's، فالكل من مشكلاتك الاقتباس تذهب بعيدا.
#!/bin/bash
args=()
for i in "$@"; do
# With Bash >= 3:
args+=(-path "$i")
# +=() doesn't work in Bash 2
# args=("${args[@]}" -path "$i")
done
exec unison "${args[@]}"
في باش، يمكنك استخدام "${@/#/-path }"
والتي ستحل محل بداية كل معلمة موضعية مع "-Path". لتمثيل نهاية استخدام السلسلة %
بدلا من #
.
إليك نص تجريبي بسيط باستخدام sed
وكررت -e
والخيارات. (بالطبع هناك طرق أكثر كفاءة للاستخدام sed
.)
#!/bin/bash
echo "Resulting arguments: ${@/#/-e }"
sed "${@/#/-e }"
وتشغيله مثل هذا:
$ echo abc | demo s/a/A/ s/b/B/
نحن نحصل:
Resulting arguments: -e s/a/A/ -e s/b/B/
ABc
إذا كنت تريد إصدار باش باش بشدة، فيمكنك أن تجرب
#! / بن / sh eval تقييم exec unison -path es ")} "
إذا قمت بإزالة جميع الأحرف التي نقلت عنها كل ثلاث مرات، يصبح هذا أسهل في فهمه، لكنني لن أفسد المرح عن طريق شرحه :-)
المضاعفات الرئيسية هي التعامل مع أسماء الملفات مع المساحات. أن الحسابات ل اقتباء Triple-Backlash ونقل مزدوج.
هنا هو كيف يمكنك أن ترضي قصور شخصياتك:
job_strategy()
{
local p
for p in "$@"; do
printf '-path\000%s\000' "$p"
done
}
job_process()
{
xargs -0 unison
}
job_strategy "path1" "path2" "path3" | job_process