سؤال

لقد كتبت نصًا يتطلب ، كحجة ، سلسلة عبارة عن سلسلة من تسلسل اسم المستخدم ومشروع. من المفترض أن يقوم البرنامج النصي بالتبديل (SU) إلى اسم المستخدم ، قرص مضغوط إلى دليل محدد يعتمد على سلسلة المشروع.

أريد أن أفعل:

su $USERNAME;  
cd /home/$USERNAME/$PROJECT;  
svn update;  

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

لقد قمت بتعبئة SU إلى أمر SVN لكن الأمر فشل (أي لم يتم تحديث SVN في الدليل المطلوب).

كيف يمكنني كتابة برنامج نصي يسمح للمستخدم بتبديل المستخدم واستدعاء SVN (من بين أشياء أخرى)؟

هل كانت مفيدة؟

المحلول

الحيلة هي استخدام أمر "sudo" بدلاً من "su"

قد تحتاج إلى إضافة هذا

username1 ALL=(username2) NOPASSWD: /path/to/svn

إلى ملف /etc /sudoers

وتغيير البرنامج النصي الخاص بك إلى:

sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update" 

عندما يكون username2 هو المستخدم الذي تريد تشغيل أمر SVN كـ username1 هو المستخدم الذي يقوم بتشغيل البرنامج النصي.

إذا كنت بحاجة إلى عدة مستخدمين لتشغيل هذا البرنامج النصي ، فاستخدم أ %groupname بدلا من اسم المستخدم 1

نصائح أخرى

أبسط بكثير: استخدم sudo لتشغيل قذيفة واستخدام أ Heredoc لإطعامه أوامر.

#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami

(إجابه في الأصل على superuser)

استخدم برنامج نصي مثل ما يلي لتنفيذ الباقي أو جزء من البرنامج النصي تحت مستخدم آخر:

#!/bin/sh

id

exec sudo -u transmission /bin/sh - << eof

id

eof

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

su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME" 

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

#!/bin/bash
if [ $UID -eq 0 ]; then
  user=$1
  dir=$2
  shift 2     # if you need some other parameters
  cd "$dir"
  exec su "$user" "$0" -- "$@"
  # nothing will be executed beyond that line,
  # because exec replaces running process with the new one
fi

echo "This will be run from user $UID"
...

يستخدم sudo في حين أن

تعديل: كما أشار دوغلاس ، لا يمكنك استخدام cd في sudo لأنه ليس خارجي أمر. يجب عليك تشغيل الأوامر في Subshell لعمل cd الشغل.

sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"

sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update

قد يُطلب منك إدخال كلمة مرور المستخدم ، ولكن مرة واحدة فقط.

لا يمكن تغيير المستخدم ضمن برنامج نصي shell. من المحتمل أن تكون الحلول باستخدام Sudo الموصوفة في إجابات أخرى أفضل رهان.

إذا كنت غاضبًا بما يكفي لتشغيل البرامج النصية Perl كجذر ، فيمكنك القيام بذلك باستخدام $< $( $> $) المتغيرات التي تحمل UID/GID حقيقية/فعالة ، على سبيل المثال:

#!/usr/bin/perl -w
$user = shift;
if (!$<) {
    $> = getpwnam $user;
    $) = getgrnam $user;
} else {
    die 'must be root to change uid';
}
system('whoami');

هذا عمل بالنسبة لي

قمت بتقسيم "توفير" من "بدء التشغيل" الخاص بي.

 # Configure everything else ready to run 
  config.vm.provision :shell, path: "provision.sh"
  config.vm.provision :shell, path: "start_env.sh", run: "always"

ثم في start_env.sh

#!/usr/bin/env bash

echo "Starting Server Env"
#java -jar /usr/lib/node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-2.40.0.jar  &
#(cd /vagrant_projects/myproj && sudo -u vagrant -H sh -c "nohup npm install 0<&- &>/dev/null &;bower install 0<&- &>/dev/null &")
cd /vagrant_projects/myproj
nohup grunt connect:server:keepalive 0<&- &>/dev/null &
nohup apimocker -c /vagrant_projects/myproj/mock_api_data/config.json 0<&- &>/dev/null &

مستوحاة من الفكرة من @مارسوفت لكنني غيرت الخطوط مثل ما يلي:

USERNAME='desireduser'
COMMAND=$0
COMMANDARGS="$(printf " %q" "${@}")"
if [ $(whoami) != "$USERNAME" ]; then
  exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS"
  exit
fi

لقد استخدمت sudo للسماح بكلمة مرور أقل تنفيذ البرنامج النصي. إذا كنت ترغب في إدخال كلمة مرور للمستخدم ، فقم بإزالة sudo. إذا كنت لا تحتاج إلى متغيرات البيئة ، فقم بإزالة -E من سودو.

ال /usr/bin/bash -l يضمن أن profile.d يتم تنفيذ البرامج النصية لبيئة تهيئة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top