मैं उस उपयोगकर्ता के रूप में बाकी बैश स्क्रिप्ट को निष्पादित करने के लिए सु का उपयोग कैसे करूं?


126

मैंने एक स्क्रिप्ट लिखी है, जो एक तर्क के रूप में, एक स्ट्रिंग जो एक उपयोगकर्ता नाम और एक परियोजना का एक संयोजन है। स्क्रिप्ट को प्रोजेक्ट स्ट्रिंग के आधार पर एक विशेष निर्देशिका में उपयोगकर्ता नाम, सीडी पर स्विच (सु) करना चाहिए।

मैं मूल रूप से करना चाहता हूं:

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

समस्या यह है कि एक बार मैं एक सु करता हूं ... यह बस वहां इंतजार करता है। जो उपयोगकर्ता के लिए स्विच करने के लिए निष्पादन के प्रवाह को पारित करने के बाद से समझ में आता है। एक बार जब मैं बाहर निकलता हूं, तो बाकी चीजें निष्पादित होती हैं, लेकिन यह वांछित के रूप में काम नहीं करता है।

मैंने sv कमांड के लिए su प्रीपेड किया, लेकिन कमांड फेल हो गया (यानी यह वांछित डायरेक्टरी में svn को अपडेट नहीं किया)।

मैं एक स्क्रिप्ट कैसे लिखूं जो उपयोगकर्ता को उपयोगकर्ता को स्विच करने और svn (अन्य चीजों के बीच) को लागू करने की अनुमति देता है?

जवाबों:


86

चाल "सु" के बजाय "सुडो" कमांड का उपयोग करना है

आपको इसे जोड़ने की आवश्यकता हो सकती है

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

आपकी / etc / sudoers फ़ाइल में

और अपनी स्क्रिप्ट को इसमें बदलें:

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

जहां उपयोगकर्ता नाम 2 है वह उपयोगकर्ता जिसे आप SVN कमांड चलाना चाहते हैं और उपयोगकर्ता नाम स्क्रिप्ट चलाने वाला उपयोगकर्ता है।

यदि आपको इस स्क्रिप्ट को चलाने के लिए कई उपयोगकर्ताओं की आवश्यकता है, %groupnameतो उपयोगकर्ता नाम 1 के बजाय का उपयोग करें


मेरे पास एक समान मुद्दा है, लेकिन मैं chshअन्य उपयोगकर्ताओं के लिए चलना चाहता था । मेरा मुद्दा यहां stackoverflow.com/q/15307289/80353 पर सूचीबद्ध है मैं अपनी स्थिति में आपके उत्तर को कैसे अनुकूलित करूं?
किम स्टैक

मैंने ऐसा किया - लेकिन फिर भी इसने मुझसे पासवर्ड मांगा।
हिप्पीजिम

@ Hippyjim क्या आप सुनिश्चित हैं कि आपने उपयोगकर्ता नाम सही तरीके से प्राप्त किया है?
किम्विस

1
मैंने किया - यह पता चला है कि मुझे / बिन / बैश के उपयोग की भी अनुमति देने की आवश्यकता है।
हिप्पीजिम

3
चाहे आप उपयोग करते हों sudoया suद्वितीयक महत्व के हों, हालाँकि sudoयह बहुत अधिक सुरक्षित और सुविधाजनक है।
ट्रिपल

105

बहुत सरल: sudoएक शेल को चलाने के लिए उपयोग करें और इसे कमांड करने के लिए एक हेरेडोक का उपयोग करें ।

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

( मूल रूप से सुपरयूजर पर उत्तर )


5
इस जवाब ने सबसे अच्छा काम किया। मैं पर्यावरण के अपेक्षित वातावरण -iपाने के लिए विकल्प का उपयोग करने की सलाह देता हूं someuser
not2savvy

2
sudoसुविधाजनक हो सकता है लेकिन यह अच्छा नहीं है अगर इसका बॉक्स से बाहर न हो (जैसे AIX पर)। su -c 'commands'सही उत्तर है।
मुश्किल

1
महाकाव्य समाधान!
3bdalla 14

चर चर के दायरे में कैसे उपलब्ध करें?
dotslashlu

AIX पर यह इस ksh को फेंकता है ksh: sh: 0403-006 निष्पादित अनुमति से वंचित।
अहमदाना

54

किसी अन्य उपयोगकर्ता के तहत स्क्रिप्ट के बाकी या भाग को निष्पादित करने के लिए निम्न की तरह एक स्क्रिप्ट का उपयोग करें:

#!/bin/sh

id

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

id

eof

11
आप "sudo -i -u ..." का उपयोग करना चाह सकते हैं ताकि यह सुनिश्चित हो सके कि $ HOME जैसी सामग्री सही तरीके से सेट की गई है।
ब्रायन लार्सन

Noob सवाल के लिए क्षमा करें, लेकिन यहाँ एक आईडी क्या है?
नितिन जाधव

1
@NitinJadhav, उन्होंने इसका उपयोग सिर्फ वर्तमान उपयोगकर्ता की आईडी दिखाने के लिए किया था, रूट की आईडी 0 है, इसलिए पहली आईडी आपको कुछ नंबर दिखाएगी, लेकिन दूसरा निश्चित रूप से 0 दिखाएगा (क्योंकि दूसरा वाला अंदर निष्पादित किया गया था) एक ब्लॉक रूट द्वारा चलाया जाता है)। आप उपयोगकर्ता के whoamiबजाय idआईडी के बजाय नाम वापस कर देंगे
मोहम्मद नौरेल्डिन

@MohammedNoureldin धन्यवाद!
नितिन जाधव

sudoसुविधाजनक हो सकता है लेकिन यह अच्छा नहीं है अगर इसका बॉक्स से बाहर न हो (जैसे AIX पर)। su -c 'commands'सही उत्तर है।
मुश्किल

52

आपको सभी अलग-अलग उपयोगकर्ता कमांड को अपनी स्क्रिप्ट के रूप में निष्पादित करने की आवश्यकता है। यदि यह सिर्फ एक है, या कुछ कमांड है, तो इनलाइन काम करना चाहिए। यदि यह बहुत सारी कमांड है तो शायद उन्हें अपनी फ़ाइल में स्थानांतरित करना सबसे अच्छा है।

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

4
यह एकमात्र सही उत्तर है। इसके लिए सूद आवश्यक नहीं है।
helvete

1
आपको शेल प्रदान करने की भी आवश्यकता हो सकती है su -s /bin/bash
मिश्रण 11

रूट उपयोगकर्ताओं के लिए सबसे अच्छा समाधान
rfinz

उन लोगों के लिए सर्वश्रेष्ठ उत्तर, जिनके पास डिफ़ॉल्ट रूप से स्थापित नहीं है (मैं आपको AIX देख रहा हूं)
ट्रिकी

46

यहाँ अभी तक एक और दृष्टिकोण है, जो मेरे मामले में अधिक सुविधाजनक था (मैं सिर्फ रूट विशेषाधिकार को छोड़ना चाहता था और प्रतिबंधित उपयोगकर्ता से मेरी स्क्रिप्ट के बाकी काम करना चाहता था): आप सही उपयोगकर्ता से स्क्रिप्ट को पुनरारंभ कर सकते हैं। मान लीजिए कि इसे शुरू में रूट के रूप में चलाया जाता है। तब यह इस तरह दिखेगा:

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

6
मुझे आश्चर्य है कि यह उच्च श्रेणी निर्धारण क्यों नहीं किया गया है। यह सब कुछ को रोक के रखते हुए मूल प्रश्न को सबसे अच्छा हल कर रहा है।
सिरवीर

या runuser -u $user -- "$@", जैसा कि su (1) में कहा गया है
cghislai

1
exec su "$user" "$0" -- "$@"
मैकिस्क

1
धन्यवाद @macieksk, अच्छा कैच। अपडेट करूंगी। --वास्तव में उपयोगी है।
मारसॉफ्ट

1
प्रस्तुत दृष्टिकोण सभी का सर्वश्रेष्ठ है और पूर्ण है। सभी को एक स्क्रिप्ट के अंदर लिखा गया है, और सभी बैश का उपयोग करते हैं। प्रभावी रूप से, इस स्क्रिप्ट को दो बार चलाया जाता है। पहले स्क्रिप्ट परीक्षण में यह रूट है, फिर पर्यावरण तैयार करें, और उपयोगकर्ता को सु द्वारा बदलें। लेकिन इसे निष्पादित कमांड के साथ करें, तो केवल एक स्क्रिप्ट उदाहरण है। दूसरे लूप के साथ, वाक्यांश यदि / फाई ommited है, तो स्क्रिप्ट सीधे तैयार कार्रवाई करती है। इस उदाहरण में यह गूंज है। अन्य सभी दृष्टिकोण आंशिक रूप से ही समस्या का समाधान करते हैं। बेशक इस स्क्रिप्ट को श
नॉट

7

sudoइसके बजाय उपयोग करें

संपादित करें : जैसा कि डगलस ने कहा, आप उपयोग नहीं कर सकते cdमें sudoहै, क्योंकि यह एक नहीं है बाह्य आदेश। आपको cdकार्य करने के लिए उप-क्रम में आदेशों को चलाना होगा ।

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

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

आपको उस उपयोगकर्ता के पासवर्ड को इनपुट करने के लिए कहा जा सकता है, लेकिन केवल एक बार।


हालांकि यह काम नहीं करेगा - पहले sudo के निष्पादन के बाद सीडी खो जाएगा।
डगलस लीडर

दरअसल, आप सीडी को सीधे कॉल भी नहीं कर सकते क्योंकि यह बाहरी कमांड नहीं है।
.ममैक

sudoसुविधाजनक हो सकता है लेकिन यह अच्छा नहीं है अगर इसका बॉक्स से बाहर न हो (जैसे AIX पर)। su -c 'commands'सही उत्तर है।
मुश्किल

6

शेल स्क्रिप्ट के भीतर उपयोगकर्ता को बदलना संभव नहीं है। अन्य उत्तरों में वर्णित सुडो का उपयोग करते हुए वर्कअराउंड शायद आपका सबसे अच्छा दांव है।

यदि आप पेरल स्क्रिप्ट को रूट के रूप में चलाने के लिए पर्याप्त पागल हैं, तो आप ऐसा उन $< $( $> $) चरों के साथ कर सकते हैं जो वास्तविक / प्रभावी यूआईडी / जीआईडी ​​रखते हैं, जैसे:

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

-1 क्योंकि यह सूडो के साथ अन्य उपयोगकर्ता के अधिकारों को अस्थायी रूप से प्राप्त करने के लिए संभव है।
किम्विस

4
यह इस अर्थ में संभव नहीं है कि उपयोगकर्ता स्वयं शेल स्क्रिप्ट चलाता है जिसे बदला नहीं जा सकता (जो कि मूल प्रश्न पूछा गया है)। सुडो के साथ अन्य प्रक्रियाओं को लागू करने से यह नहीं बदलता है कि स्क्रिप्ट स्वयं के रूप में चल रही है।
पी-नट्स

2

इसने मेरे लिए काम किया

मैंने अपने "स्टार्टअप" से "प्रावधान" को विभाजित किया।

 # 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

@ MarSoft से विचार से प्रेरित लेकिन मैंने निम्नलिखित की तरह लाइनें बदल दीं :

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। यदि आपको पर्यावरण चर की आवश्यकता नहीं है, तो -Esudo से निकालें ।

यह /usr/bin/bash -lसुनिश्चित करता है, कि profile.dएक आरंभिक वातावरण के लिए लिपियों का निष्पादन किया जाता है।


sudoसुविधाजनक हो सकता है लेकिन यह अच्छा नहीं है अगर इसका बॉक्स से बाहर न हो (जैसे AIX पर)। su -c 'commands'सही उत्तर है।
मुश्किल

@ ट्रिकी शायद पूरा जवाब पढ़ें, यह पहले से ही हटाने का सुझाव देता है sudo। वास्तव में, sudo इतना सरल नहीं है, बहुत सारे मामलों में आपको sudo -Eसम्‍मिलित करने और sudoers.d में कॉन्फ़िगरेशन प्रविष्टि की आवश्यकता होती है , जिसके साथ tty के बिना निष्पादन की अनुमति है !requiretty। लेकिन ऐसे बहुत से मामले हैं, जहाँ स्वचालित नामक लिपियों के लिए sudo आवश्यक है, जहाँ एक पासवर्ड डायलॉग हस्तक्षेप कर सकता है। इस प्रकार मैं इसे एक मानक समाधान से नहीं हटाऊंगा।
ट्रेंडफिशर

प्रश्न में कोड एक समान छोटी गाड़ी है - यह रिक्त स्थान के साथ स्क्रिप्ट के नाम या तर्क को तोड़ देगा; ध्यान रखें कि "$@"एक स्ट्रिंग के अंदर डालने का मतलब है कि पहले वाले तर्क को एक अलग स्ट्रिंग में जोड़ा गया है, तर्क में शामिल नहीं-c है। यदि आप इसे सुरक्षित बनाना चाहते हैं, तो आप शायद printf -v arg_q '%q ' "$0" "$@"इस्तेमाल कर सकते हैंsu "$USERNAME" -c "/usr/bin/bash -l $arg_q"
चार्ल्स डफी

@CharlesDuffy आप सही कह रहे हैं! मैंने इस उत्तर के लिए अपनी प्रोडक्शन स्क्रिप्ट को बहुत सरल बनाया :-( बस COMMANDARGS=$@समस्या को हल करने के साथ जोड़ रहा है -c। रिक्त स्थान के साथ तर्क पहले कोई समस्या नहीं थी, लेकिन मैंने आपका अच्छा इनपुट लागू किया। मुझे इसे काम करने के लिए कुछ प्रयोग करने थे। " 'सवाल संपादित किया है और उम्मीद है कि मैं एक और बग पेस्ट नहीं किया था। आपकी टिप्पणी के लिए धन्यवाद, अपमानजनक लेकिन आवश्यक है।
ट्रेंडफिशर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.