web-dev-qa-db-ja.com

suを使用して残りのbashスクリプトをそのユーザーとして実行するにはどうすればよいですか?

ユーザー名とプロジェクトを連結した文字列を引数として取るスクリプトを作成しました。スクリプトはユーザー名に切り替え(su)、プロジェクト文字列に基づいて特定のディレクトリにcdすることになっています。

私は基本的にやりたい:

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

問題は、一度suを実行すると、そこに待機することです。実行のフローがユーザーへの切り替えに渡されているため、これは理にかなっています。いったん終了すると、残りの処理が実行されますが、期待どおりに機能しません。

Svnコマンドの前にsuを追加しましたが、コマンドは失敗しました(つまり、目的のディレクトリのsvnを更新しませんでした)。

ユーザーが(特に)ユーザーを切り替えてsvnを起動できるようにするスクリプトを作成するにはどうすればよいですか?

113
Avery

秘Theは、「su」の代わりに「Sudo」コマンドを使用することです

これを追加する必要があるかもしれません

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

/ etc/sudoersファイルに

スクリプトを次のように変更します。

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

Username2はSVNコマンドを実行するユーザーであり、username1はスクリプトを実行するユーザーです。

このスクリプトを実行するために複数のユーザーが必要な場合は、username1の代わりに%groupnameを使用します

81
Kimvais

もっと簡単:Sudoを使用してシェルを実行し、 heredoc を使用してコマンドをフィードします。

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

(答え 元々はスーパーユーザー

87
Dan Dascalescu

次のようなスクリプトを使用して、他のユーザーの下でスクリプトの残りまたは一部を実行します。

#!/bin/sh

id

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

id

eof
53
Walder

すべての異なるユーザーコマンドを独自のスクリプトとして実行する必要があります。それが1つまたはいくつかのコマンドである場合、インラインは動作するはずです。多数のコマンドがある場合は、独自のファイルに移動することをお勧めします。

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

私の場合はさらに便利な別のアプローチがあります(root権限を削除し、残りのスクリプトを制限ユーザーから実行したかっただけです):正しいユーザーからスクリプトを再起動することができます。最初にルートとして実行されると仮定しましょう。次に、このようになります:

#!/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"
...
35
MarSoft

代わりにSudoを使用してください

EDIT:ダグラスが指摘したように、cdexternalコマンドではないため、Sudoで使用できません。 cdを機能させるには、サブシェルでコマンドを実行する必要があります。

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

そのユーザーのパスワードの入力を求められる場合がありますが、一度だけです。

7
iamamac

シェルスクリプト内でユーザーを変更することはできません。他の回答に記載されているSudoを使用した回避策がおそらく最善の策です。

RootとしてPerlスクリプトを実行するのに十分怒っている場合、実/有効なuid/gidを保持する$< $( $> $)変数を使用してこれを行うことができます。

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

これは私のために働いた

「プロビジョニング」を「スタートアップ」から分離しました。

 # 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 &
2
httpete