سؤال تنفيذ أمر من دليل آخر في باش


قل أني أفعل هذا:

cd subdir
git init
cd ../

هل هناك طريقة للقيام بذلك من خلال أمر واحد ، أو ربما اثنين ، بدلا من الاضطرار إلى الدخول والخروج من الدليل من أجل تشغيل الأمر هناك؟

(لا تبحث عن حل خاص بـ git ؛ هذا مجرد مثال).


97
2018-04-17 16:05


الأصل




الأجوبة:


هذه غالبًا ما تكون أفضل طريقة:

( cd dir ; git init )

أو

( cd dir && git init )

انها قصيرة جدا وسهلة للكتابة. إنها لا تبدأ بصدفة فرعية ، لذا لا يمكنك تعديل بيئتك من ذلك ، ولكن لا يبدو أن هذه مشكلة هنا.


170
2018-04-17 16:27



وإذا كنت بحاجة إلى تعيين متغير بيئة أو اثنين ، فما عليك سوى إضافة ذلك كإجراء آخر في البداية. - Hippo
CraigMcQueen: ليس حقا. $? سيحتوي على رمز إنهاء الأمر الأخير الذي تم تشغيله في القائمة الفرعية. إذا كنت تستخدم && البديل (الذي يجب عليك عادة) ، ثم ستحصل على رمز الخروج للأمر الأول الذي فشل (أو صفر إذا كان كل شيء على ما يرام). - Mat
أعتقد أن الأقواس اختيارية - Francis.Beauchamp
@ Francis.Beauchamp: إذا قمت بحذف parens ، فسوف تكون في subdir بعد الأمر بدلاً من الخلف حيث بدأت. - Mat


كنت أبحث عن طريقة لتنفيذ أمر git من مسار ، وإجراء تغييرات على المستودع في مسار مختلف. لذا انتهى بي المطاف في هذا السؤال هنا.

ولكن بالنسبة لحاجاتي الخاصة ، لم تساعد الإجابة المقبولة ولا أي من الأسئلة الأخرى.

كنت بحاجة لتشغيل أوامر git باستخدام sudo -u USER /usr/bin/git (مستخدم آخر يشغلها). وكما تعلمون ، لا يسمح لي sudo بتشغيل cd الأمر ، لذلك لا أستطيع يكون في دليل المستودع.

لذا ، ذهبت إلى صفحة الرجل جيت. ومن بين الخيارات ، رأيت --git-dir=<path>:

--git-دير =

قم بتعيين المسار إلى المستودع. ويمكن أيضًا التحكم في ذلك عن طريق تعيين متغير بيئة GIT_DIR. يمكن أن يكون مسارًا مطلقًا أو مسارًا نسبيًا لدليل العمل الحالي.

لذلك ، إذا كان ذلك يساعد شخصًا ما ، فلا يزال بإمكانك استخدام بوابة من مسار وإجراء تغييرات على مستودع "بعيد عنك". مجرد استخدام:

git --git-dir=/path/to/repository GIT_COMMAND

أو ، لتشغيله كمستخدم آخر ، افعل شيئًا مثل:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository GIT_COMMAND

أيضا من git-init الصفحة الرجل:

إذا تم تعيين متغير البيئة GIT_DIR $ ، فإنه يحدد مسارًا لاستخدامه بدلاً من ./.git لقاعدة المخزون.

لذا ، إذا كنت تريد بدء المستودع ضمن مجلد .git المعتاد ، فستحتاج إلى تحديده مع --git-dir اختيار. على سبيل المثال:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository/.git init

بعد تهيئة المستودع على /path/to/repo/.git، يجب أن يكون جميع الأوامر الإضافية الخيار --work-tree=<path>، كما هو موضح في صفحة الرجل في جيت:

--work شجرة =

قم بتعيين المسار إلى شجرة العمل. يمكن أن يكون مسارًا مطلقًا أو مسارًا متعلقًا بدليل العمل الحالي. ويمكن أيضًا التحكم في ذلك عن طريق تعيين متغير بيئة GIT_WORK_TREE ومتغير تكوين core.worktree (راجع core.worktree في git-config (1) لمزيد من المناقشة التفصيلية).

لذا ، فإن الأمر الصحيح لتشغيل git كمستخدم آخر ، وتهيئة مستودع جديد هو:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository/.git init
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' add /path/to/repository/*
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' commit -m 'MESSAGE'
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' remote add origin user@domain.com:path
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' push -u origin master

21
2018-06-20 23:56



إذا كنت تستخدم sudo بشكل تفاعلي وليس من خلال نص ، يمكنك ببساطة القيام بذلك sudo -i أو sudo su للحصول على غلاف جذر تفاعلي. - Bugster


ليس بالضبط ما تسأل (لديك إجابات حقيقية أعلاه مع subshell) ولكن انظر pushd و popd


12
2018-04-17 17:39



لقد حاولت مع قرص مضغوط && لمخضر وأنه لا يعمل ، ولكن pushd و popd يقوم بهذه المهمة تماما. شكر - Radu Toader


لديك بعض الخيارات. يمكنك إما تجميع الأوامر مع && أو ;. مثله:

cd subdir && git init && cd ..

أو

cd subdir; git init; cd ..

الفرق بينهما هو أنه في المثال الأول ، إذا فشلت إحدى الأوامر ، فلن تقوم بتنفيذ بقية هذه الأوامر. في المثال الثاني ، سيتم تشغيل جميع الأوامر مهما كانت.

خيار آخر هو تحديد وظيفة واستخدامها ، على سبيل المثال:

function cdinit() {
    cd $1
    git init
    cd ..
}

ثم يمكنك تشغيل الأمر:

cdinit subdir

وسوف تلقائيا git init في هذا الدليل والخروج منه.

يمكنك أيضًا إجراء حل أكثر تعقيدًا باستخدام إحدى الوظائف إذا كان لديك مجموعة من الأدلة وتريد ذلك git init لهم بأمر واحد.

function cdinit() {
    for arg in $@
    do
        cd $arg
        git init
        cd ..
    done
}

يمكنك بعد ذلك تشغيل هذا مع:

cdinit subdir1 subdir2 subdir3

وسوف تفعل git init في subdir1، subdir2و subdir3.


5
2018-04-17 16:17



شكر. كنت على علم && و ;، لكنه يأمل في شيء أكثر أناقة. يبدو وكأنه كتابة السيناريو هو أفضل خيار لدي. - Trevor Burnham
تصحيح: هذه الإجابة على ما يرام ، ولكن الجواب مات أفضل لحاجاتي الخاصة. - Trevor Burnham


في حالة git (على الأقل في الإصدار 2.7.0) ، يمكنك الاستفادة من -C الخيار الذي يجعل git تتصرف كما لو كانت قد بدأت في الدليل المحدد. لذلك قد يبدو حلك:

> git -C subdir init
Initialized empty Git repository in /some/path/subdir/.git/

نقلا عن الوثائق:

Run as if git was started in <path> instead of the current working directory. When multiple -C options are given, each subsequent non-absolute -C
<path> is interpreted relative to the preceding -C <path>.

This option affects options that expect path name like --git-dir and --work-tree in that their interpretations of the path names would be made
relative to the working directory caused by the -C option. 

5
2018-02-19 15:14





يمكنك تجميع الأوامر مع && ، مثل

cd subdir && git init && cd ../

إذا كنت لا تريد أي تبعية على رمز الخروج لكل أمر ، فيمكنك استخدامه ؛ بدلا من ذلك ، أي:

cd subdir ; git init ; cd ../

2
2018-04-17 16:09



أو مع ; بحيث لا تعتمد على رمز الإرجاع الخاص بالرمز السابق. - slhck


يجب عليك القفز في دليل الهدف الخاص بك إذا كان الأمر لا يحتوي على اسم ملف أو اسم اسم المعلمة.

ولكن يمكنك كتابة برنامج نصي bash يأخذ الدليل المستهدف والأمر كمعلمات. لهذا يمكنك إلقاء نظرة على pushd و popd: http://ss64.com/bash/pushd.html

أود أن أكتب هذا البرنامج النصي الصغير بالنسبة لك ، ولكن ليس لدي مربع لينكس هنا :)


2
2018-04-17 16:18



فقط رأيت الإجابة من مارك Szymanski. يمكنك فقط تنفيذ معلمة ثانية لأمر (وإعادة تسمية الأمر) ولديك ما تريد. - wullxz


برامج لديها طرق مختلفة للتعامل مع الحجج ، لذلك فإن عددا قليلا سيكون لها ما يعادل -folder = اسم اختيار. أبعد من هذا الاستثناء ، المعيار ، حتى على MS DOS ، هو ببساطة

$ برنامج subdir

في بعض الأحيان تحتاج

$ برنامج subdir /

سيقوم البرنامج بفتح المجلد ، والعمل معه بالطريقة نفسها التي تعمل بها مع ملف ، وبمجرد الانتهاء ، قم بإعادة التحكم إلى shell الخاص بك ، والذي يشير إلى الدليل القياسي الأصلي. البرامج التي تتم معالجتها بهذه الطريقة يكون لديك مشكلة في أن مخرجات الخطأ (مثل عمليات التفريغ الأساسية) تذهب إلى ملف في الدليل الحالي لـ shell (بدلاً من subdir.)

لا يوجد أي حل ما لم يكن البرنامج يحتوي على رموز تبديل متوفرة لتحديد مكان مختلف. بعض المبرمجين يأخذون رخصة فنية بين "برنامج الدليل كان دعا من"و" كان برنامج الدليل وقال للعمل في ".


1
2018-04-17 16:40