मैं उन फ़ाइलों की प्रतिलिपि कैसे बना सकता हूं, जिन्हें scp के साथ रूट एक्सेस की आवश्यकता है?


167

मेरे पास एक Ubuntu सर्वर है, जिसे मैं SSH का उपयोग करके कनेक्ट कर रहा हूं।

मुझे /var/www/सर्वर पर अपनी मशीन से फाइलें अपलोड करने की जरूरत है , फाइलें /var/www/स्वामित्व में हैं root

पुट्टी का उपयोग करते हुए, मैं लॉग इन करने के बाद, मुझे sudo suफ़ाइलों को संशोधित करने में सक्षम होने के लिए पहले अपना पासवर्ड टाइप करना होगा /var/www/

जब मैं WinSCP का उपयोग करके फ़ाइलों की प्रतिलिपि बना रहा हूं, तो मैं फ़ाइलों को बना / संशोधित नहीं कर सकता /var/www/, क्योंकि मैं जिस उपयोगकर्ता से जुड़ रहा हूं, उसके पास फ़ाइलों पर अनुमतियाँ नहीं हैं /var/www/और मैं यह नहीं कह सकता कि sudo suमैं ssh सत्र के मामले में क्या करूं ।

क्या आप जानते हैं कि मैं इससे कैसे निपट सकता हूं?

यदि मैं अपनी स्थानीय मशीन पर काम कर रहा था, तो मैं फोन करूंगा gksudo nautilusलेकिन इस मामले में मेरे पास केवल मशीन तक टर्मिनल पहुंच है।


यह आपके वर्चुअल सर्वर प्रदाता के लिए, या पोटीन या wincp डेवलपर्स के लिए एक प्रश्न जैसा लगता है।
dobey

7
@dobey आप गलत तरीके से गलत है, यह ubuntu विशेषाधिकार के बारे में है!
दिमित्रिस सपिकास

7
यह बंद क्यों है? यह scp के साथ फ़ाइलों की नकल करने के बारे में एक पूरी तरह से वैध प्रश्न है - हर वेब डेवलपर इस स्थिति से परिचित है
सर्गेई


मुझे एक ऐसी ही समस्या है। मैं विंडोज कंप्यूटर पर एक फ़ाइल (इस मामले में HTML) बनाता हूं और इसे WinSCP के साथ / var / www / html / वेबसाइट फ़ोल्डर में कॉपी करने का प्रयास करता हूं। और यह कहता है कि अनुमति की समस्या है। क्योंकि मैं अपने / होम फोल्डर में कॉपी कर सकता हूं, मैंने फाइल को दो चरणों में कॉपी किया, लेकिन यह बहुत सुविधाजनक नहीं है :-) मैंने अपने उपयोगकर्ता को www-data समूह में जोड़ने की कोशिश की, लेकिन इससे कोई मदद नहीं मिली। Www-data में उपयोगकर्ता को जोड़ने का कोई भी विचार अभी भी उपयोगकर्ता को www-डेटा समूह के स्वामित्व वाले फ़ोल्डर में फ़ाइल की प्रतिलिपि बनाने की अनुमति नहीं देता है?
JanezKranjski

जवाबों:


125

आप सही हैं, sudoजब कोई काम नहीं करता है scp। वर्कअराउंड scpफ़ाइलों को एक निर्देशिका में अपलोड करने के लिए उपयोग करना है जहां आपके उपयोगकर्ता के पास फ़ाइलों को बनाने की अनुमति है, फिर ssh के माध्यम से लॉग इन करें और sudoफ़ाइलों को अपने अंतिम गंतव्य पर ले जाने / कॉपी करने के लिए उपयोग करें।

scp -r folder/ user@server.tld:/some/folder/you/dont/need/sudo
ssh user@server.tld
 $ sudo mv /some/folder /some/folder/requiring/perms 
# YOU MAY NEED TO CHANGE THE OWNER like:
# sudo chown -R user:user folder

एक अन्य समाधान उन फ़ाइलों को अपलोड करने वाली निर्देशिकाओं की अनुमतियाँ / स्वामित्व बदलना होगा, ताकि आपका गैर-विशेषाधिकार प्राप्त उपयोगकर्ता उन निर्देशिकाओं में लिख सके।

आम तौर पर, rootखाते में काम करना एक अपवाद होना चाहिए, एक नियम नहीं - जिस तरह से आप अपने सवाल को फिर से बना रहे हैं, मुझे लगता है कि शायद आप इसे थोड़ा गाली दे रहे हैं, जो बदले में अनुमति के साथ समस्याओं की ओर जाता है - सामान्य परिस्थितियों में आपको ज़रूरत नहीं है अपनी खुद की फ़ाइलों का उपयोग करने के लिए सुपर-व्यवस्थापक विशेषाधिकार।

तकनीकी रूप से, आप उबंटू को दूरस्थ रूप से सीधे लॉगिन करने की अनुमति देने के लिए कॉन्फ़िगर कर सकते हैं root, लेकिन यह सुविधा एक कारण से अक्षम है, इसलिए मैं आपको ऐसा करने के खिलाफ दृढ़ता से सलाह दूंगा।


मुझे पहला उपाय नहीं मिला, क्या आप कृपया एक मुकदमे को और अधिक प्रभावशाली बना सकते हैं?
दिमित्रिस सपिकास

Whe मैं कहता हूं कि मेरी खुद की फाइलें i / var / www, मैं अपने vps का उपयोग वेब सर्वर के रूप में कर रहा हूं .... मेरे खुद के फ़ोल्डर में मेरी पूरी पहुंच है
दिमित्रीस सपनिका

7
पुन। पहला समाधान। 1. scp -R mysite dimitris@myserver.com:/home/dimitris/2. ssh dimitris@myserver.com3. sudo mv ~/mysite /var/www- यह एक 2-चरण की प्रक्रिया है, पहले आप scpअपने घर की फाइलों को डीआईआर में डालते हैं, फिर आप ssh के माध्यम से लॉग इन करते हैं और फाइलों को उन
सर्गेई

36

एक और तरीका है स्कैप के बजाय टार + एसश का उपयोग करके कॉपी करना:

tar -c -C ./my/local/dir \
  | ssh dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www"

2
यह इसे करने का सबसे अच्छा तरीका है।
mttdbrd

2
मुझे यह विधि सफलतापूर्वक काम करने के लिए नहीं मिल रही है। जैसा लिखा है मुझे मिलता है sudo: sorry, you must have a tty to run sudo। अगर मैं TTY आवंटित करने के लिए "-t" जोड़ता हूं तो मुझे मिलता है Pseudo-terminal will not be allocated because stdin is not a terminal.। मैं बिना पासवर्ड सूडो के इस काम को नहीं देख सकता।
IBBoard

1
@IBBard: ssh -t का उपयोग करके यहां समाधान का प्रयास करें :ssh -t dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www"
अलेक्जेंडर बर्ड

2
@AlexanderBird जबकि वह कई मामलों में काम करता है, मुझे यकीन नहीं है कि यह यहाँ काम करता है क्योंकि हम SSH कनेक्शन पर एक टारबॉल को पाइप करने की कोशिश कर रहे हैं। देखें serverfault.com/questions/14389/...
द्वारा IBBoard

यही मेरे लिए आखिरकार काम आया। आप एक दूरस्थ फ़ाइल की अनुमतियां कि आप स्थानीय को कॉपी करने के लिए एक करते हैं, चाहते हैं नहीं है sudo tarका उपयोग करते हुए, उसे संग्रहीत, परिवर्तन अनुमतियों chmodऔर chown, और फिर इसे स्थानीय करने के लिए नकल। खासकर अगर यह एक निर्देशिका है।
फोरम्यूलेटर

27

तेज तरीका

सर्वर से स्थानीय मशीन तक:

ssh user@server "sudo cat /etc/dir/file" > /home/user/file

स्थानीय मशीन से सर्वर तक:

cat /home/user/file | ssh user@server "sudo tee -a /etc/dir/file"

5
यह उत्तर रेखांकित है। यह एक एकल परमाणु ऑपरेशन के साथ एक रूट फाइल को सरल, स्वच्छ, पढ़ता है या लिखता है, और इसके लिए आपको स्कूप का उपयोग करने की आवश्यकता नहीं है। मुख्य दोष यह है कि यह अनुमतियों की नकल नहीं करता है। यदि आप चाहते हैं कि, टार समाधान बेहतर है। यह एक शक्तिशाली तकनीक है, खासकर अगर xargs / bash मैजिक को ट्रैवर्स पथों के साथ जोड़ दिया जाए ..
markgo2k

मुझे लगता है कि सवाल स्थानीय से रिमोट पर एक फाइल अपलोड करने के बारे में था और इसके विपरीत नहीं
कोरयेम

1
खूबसूरती से किया। यह वही है जो मैं ऊपर और नीचे दोनों के लिए देख रहा था। धन्यवाद
जेरेमी

सुनिश्चित करने के लिए शीर्ष उत्तर होने का वर्णन करता है।
एंड्रयू वाटसन

यह एक फ़ाइल के बजाय एक निर्देशिका के लिए किया जा सकता है?
ल्यूसिडब्रोट

26

आप इसे ansibleपूरा करने के लिए भी उपयोग कर सकते हैं ।

Ansible के copyमॉड्यूल का उपयोग करके दूरस्थ होस्ट पर कॉपी करें :

ansible -i HOST, -b -m copy -a "src=SRC_FILEPATH dest=DEST_FILEPATH" all

Ansible के fetchमॉड्यूल का उपयोग करके दूरस्थ होस्ट से प्राप्त करें :

ansible -i HOST, -b -m fetch -a "src=SRC_FILEPATH dest=DEST_FILEPATH flat=yes" all

ध्यान दें:

  • -i HOST,वाक्य रचना में अल्पविराम टाइपो नहीं है। यह इन्वेंट्री फ़ाइल की आवश्यकता के बिना ansible का उपयोग करने का तरीका है।
  • -bसर्वर पर क्रियाओं को मूल के रूप में करने का कारण बनता है। -bकरने के लिए फैलता है --become, और डिफ़ॉल्ट --become-userमूल है, डिफ़ॉल्ट --become-methodहोने के साथ sudo।
  • flat=yesकेवल फ़ाइल की प्रतिलिपि बनाता है , संपूर्ण दूरस्थ पथ को फ़ाइल तक ले जाता है
  • फ़ाइल पथों में वाइल्डकार्ड का उपयोग इन ansible मॉड्यूल द्वारा समर्थित नहीं है।
  • निर्देशिका को कॉपी करना copyमॉड्यूल द्वारा समर्थित है , लेकिन मॉड्यूल द्वारा नहींfetch

इस प्रश्न के लिए विशिष्ट आह्वान

यहां एक उदाहरण है जो विशिष्ट और पूरी तरह से निर्दिष्ट है, वितरित की जाने वाली फ़ाइलों से युक्त आपके स्थानीय होस्ट की निर्देशिका को मानते हुए sourcedir, और यह है कि दूरस्थ लक्ष्य का होस्टनाम है hostname:

cd sourcedir && \
ansible \
   --inventory-file hostname, \ 
   --become \
   --become-method sudo \
   --become-user root \
   --module-name copy \
   --args "src=. dest=/var/www/" \
   all

संक्षिप्त आमंत्रण के साथ:

cd sourcedir && \
ansible -i hostname, -b -m copy -a "src=. dest=/var/www/" all

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


मुझे यह उत्तर पसंद है लेकिन मैं आपको सलाह देता हूं कि पूछे गए प्रश्न पर इसे निर्देशित करें। कुछ इस तरहansible -i "hostname," all -u user --become -m copy -a ...
माइक डी

@ माइक: उपरोक्त परिवर्तन कैसे दिखते हैं?
erik.weathers

1
क्या कुछ -i 'host,'मान्य सिंटैक्स होगा? मुझे लगता है कि कमांड पढ़ते समय इस तरह से विराम चिह्न खोना आसान है। (पाठक के लिए मेरा मतलब है, अगर खोल नहीं है।)
म्वफेरेन्ले

1
@ mwfearnley: निश्चित रूप से, शेल उपचार करेगा -i 'host,'और जैसा -i host,या वैसा ही होगा -i "host,"। सामान्य तौर पर मैं इन आक्रमणों को जितना संभव हो सके उतना कम रखना पसंद करता हूं, लेकिन आपको स्वतंत्र महसूस करना चाहिए क्योंकि यह स्पष्टता के लिए आवश्यक है जैसा कि आपको लगता है कि यह क्रिया और स्पष्ट है।
erik.weathers

2
बॉक्स के बाहर जाने का रास्ता! Ansible का महान उपयोग
jonatan

12

जब आप चलाते हैं sudo su, तो आपके द्वारा बनाई गई कोई भी फ़ाइल रूट के स्वामित्व में होगी, लेकिन डिफ़ॉल्ट रूप से सीधे ssh या scp के साथ रूट के रूप में लॉग इन करना संभव नहीं है। स्कोप के साथ सुडो का उपयोग करना भी संभव नहीं है, इसलिए फाइलें उपयोग करने योग्य नहीं हैं। अपनी फ़ाइलों पर स्वामित्व का दावा करके इसे ठीक करें:

अपने उपयोगकर्ता नाम को डिमिट्री मानकर, आप इस कमांड का उपयोग कर सकते हैं।

sudo chown -R dimitri:dimitri /home/dimitri

तब से, जैसा कि अन्य उत्तरों में बताया गया है, "उबंटू" रास्ता सूडो का उपयोग करना है, न कि रूट लॉगिन। यह एक उपयोगी प्रतिमान है, जिसमें महान सुरक्षा लाभ हैं।


मैं किसी भी तरह से इस समाधान का उपयोग कर रहा हूं, लेकिन क्या होगा अगर मैं अपनी खुद की फ़ाइल प्रणाली तक पूरी पहुंच प्राप्त कर सकता हूं, मैं sudo chow ...हर एक निर्देशिका के लिए टाइप नहीं करना चाहता : S
दिमित्रिस सपिकास

2
पासिंग सुविधा के लिए उपयोगकर्ता के लिए सभी सिस्टम फ़ाइलों का स्वामित्व बदलना अत्यधिक हतोत्साहित करता है। यह किसी भी उपयोगकर्ता के बग को आपके सिस्टम की सुरक्षा से गंभीर रूप से समझौता करने की अनुमति दे सकता है। फ़ाइलों के स्वामित्व को बदलने के लिए बेहतर है कि आपको एससीपी द्वारा बदलने या अपडेट करने की आवश्यकता है, लेकिन सब कुछ रूट के स्वामित्व में छोड़ दें (जैसे कि यह माना जाता है)। जिसके अनुसार, -Rमें chownयह बताता है कि निर्देशिका का स्वामित्व बदलने के लिए, और सभी बच्चों फ़ाइलों और निर्देशिकाओं रिकर्सिवली ... ताकि आप आप की तरह कुछ भी कर सकते हैं।
ट्रिगमेंन्डर्स

हम्म .... जो ठीक काम कर रहा है, धन्यवाद! क्षमा करें, मैं इसे बढ़ा नहीं सकता (सिस्टम मुझे करने की अनुमति नहीं देता ...)
दिमित्रिस सपिकास

11

SSH के ऊपर rsync( Windows में Cygwin / cwRsync ) का उपयोग करने का सबसे अच्छा तरीका हो सकता है ?

उदाहरण के लिए, स्वामी के साथ फ़ाइलें अपलोड करने के लिए www-data:

rsync -a --rsync-path="sudo -u www-data rsync" path_to_local_data/ login@srv01.example.com:/var/www

आपके मामले में, यदि आपको रूट विशेषाधिकारों की आवश्यकता है, तो कमांड इस तरह होगी:

rsync -a --rsync-path="sudo rsync" path_to_local_data/ login@srv01.example.com:/var/www

देखें: sudo के साथ दूरस्थ सर्वर से scp


5

यदि आप PuTTY के बजाय OpenSSH टूल का उपयोग करते हैं, तो आप scpसर्वर पर फ़ाइल स्थानांतरण आरंभ करके इसे पूरा कर सकते हैं sudo। सुनिश्चित करें कि आपके पास sshdअपने स्थानीय मशीन पर चलने वाला डेमन है। साथ ssh -Rआप सर्वर अपने मशीन संपर्क करने के लिए एक तरह से दे सकते हैं।

आपकी मशीन पर:

ssh -R 11111:localhost:22 REMOTE_USERNAME@SERVERNAME

सर्वर पर आपको लॉग इन करने के अलावा, यह सर्वर के पोर्ट 11111 पर आपकी मशीन के पोर्ट 22 पर किए गए हर कनेक्शन को आगे बढ़ाएगा: जिस पोर्ट पर आप sshdसुन रहे हैं।

सर्वर पर, फ़ाइल स्थानांतरण इस तरह शुरू करें:

cd /var/www/
sudo scp -P 11111 -r LOCAL_USERNAME@localhost:FOLDERNAME .

1

आप इस विषय से प्रेरित होकर लिखी गई स्क्रिप्ट का उपयोग कर सकते हैं:

touch /tmp/justtest && scpassudo /tmp/justtest remoteuser@ssh.superserver.com:/tmp/

लेकिन इसके लिए कुछ पागल सामान की आवश्यकता होती है (जो कि btw है। स्वचालित रूप से स्क्रिप्ट द्वारा किया जाता है)

  1. सर्वर जो फ़ाइल भेजी जा रही है वह अब स्रोत कंप्यूटर से ssh कनेक्शन स्थापित करते समय पासवर्ड नहीं मांगेगा
  2. सर्वर पर sudo प्रॉम्प्ट की कमी की आवश्यकता के कारण, sudo अब उपयोगकर्ता के लिए रिमोट मशीन पर पासवर्ड नहीं मांगेगा

यहाँ स्क्रिप्ट जाती है:

interface=wlan0
if [[ $# -ge 3 ]]; then interface=$3; fi
thisIP=$(ifconfig | grep $interface -b1 | tail -n1 | egrep -o '[0-9.]{4,}' -m1 | head -n 1)
thisUser=$(whoami)
localFilePath=/tmp/justfortest
destIP=192.168.0.2
destUser=silesia
#dest 
#destFolderOnRemoteMachine=/opt/glassfish/glassfish/
#destFolderOnRemoteMachine=/tmp/

if [[ $# -eq 0 ]]; then 
echo -e "Send file to remote server to locatoin where root permision is needed.\n\tusage: $0 local_filename [username@](ip|host):(remote_folder/|remote_filename) [optionalInterface=wlan0]"
echo -e "Example: \n\ttouch /tmp/justtest &&\n\t $0 /tmp/justtest remoteuser@ssh.superserver.com:/tmp/ "
exit 1
fi

localFilePath=$1

test -e $localFilePath 

destString=$2
usernameAndHost=$(echo $destString | cut -f1 -d':')

if [[ "$usernameAndHost" == *"@"* ]]; then
destUser=$(echo $usernameAndHost | cut -f1 -d'@')
destIP=$(echo $usernameAndHost | cut -f2 -d'@')
else
destIP=$usernameAndHost
destUser=$thisUser
fi

destFolderOnRemoteMachine=$(echo $destString | cut -f2 -d':')

set -e #stop script if there is even single error

echo 'First step: we need to be able to execute scp without any user interaction'
echo 'generating public key on machine, which will receive file'
ssh $destUser@$destIP 'test -e ~/.ssh/id_rsa.pub -a -e ~/.ssh/id_rsa || ssh-keygen -t rsa'
echo 'Done'

echo 'Second step: download public key from remote machine to this machine so this machine allows remote machine (this one receiveing file) to login without asking for password'

key=$(ssh $destUser@$destIP 'cat ~/.ssh/id_rsa.pub')
if ! grep "$key" ~/.ssh/authorized_keys; then
echo $key >> ~/.ssh/authorized_keys
echo 'Added key to authorized hosts'
else
echo "Key already exists in authorized keys"
fi

echo "We will want to execute sudo command remotely, which means turning off asking for password"
echo 'This can be done by this tutorial http://stackoverflow.com/a/10310407/781312'
echo 'This you have to do manually: '
echo -e "execute in new terminal: \n\tssh $destUser:$destIP\nPress enter when ready"
read 
echo 'run there sudo visudo'
read
echo 'change '
echo '    %sudo   ALL=(ALL:ALL) ALL'
echo 'to'
echo '    %sudo   ALL=(ALL:ALL) NOPASSWD: ALL'
echo "After this step you will be done."
read

listOfFiles=$(ssh $destUser@$destIP "sudo ls -a")

if [[ "$listOfFiles" != "" ]]; then 
echo "Sending by executing command, in fact, receiving, file on remote machine"
echo 'Note that this command (due to " instead of '', see man bash | less -p''quotes'') is filled with values from local machine'
echo -e "Executing \n\t""identy=~/.ssh/id_rsa; sudo scp -i \$identy $(whoami)@$thisIP:$(readlink -f $localFilePath) $destFolderOnRemoteMachine"" \non remote machine"
ssh $destUser@$destIP "identy=~/.ssh/id_rsa; sudo scp -i \$identy $(whoami)@$thisIP:$(readlink -f $localFilePath) $destFolderOnRemoteMachine"
ssh $destUser@$destIP "ls ${destFolderOnRemoteMachine%\\\\n}/$(basename $localFilePath)"
if [[ ! "$?" -eq 0 ]]; then echo "errror in validating"; else echo -e "SUCCESS! Successfully sent\n\t$localFilePath \nto \n\t$destString\nFind more at http://arzoxadi.tk"; fi
else
echo "something went wrong with executing sudo on remote host, failure"

fi
ENDOFSCRIPT
) | sudo tee /usr/bin/scpassudo && chmod +x /usr/bin/scpassudo

@Braiam हाँ, यकीन है, लिंक के लिए खेद है, स्क्रिप्ट बहुत लंबा है और यही कारण था :)
Test30

1

आप ssh, sudo और जैसे टार को सर्वर में फ़ाइलों को स्थानांतरित करने के लिए बिना रूट में लॉग इन किए और अपने उपयोगकर्ता के साथ फ़ाइलों को एक्सेस करने की अनुमति नहीं होने के लिए जोड़ सकते हैं। यह थोड़ा फिजूल है, इसलिए मैंने इसकी मदद के लिए एक स्क्रिप्ट लिखी है। आप स्क्रिप्ट यहां पा सकते हैं: https://github.com/sigmunau/sudoscp

या इधर:

#! / Bin / bash
रेस = 0
= $ 1 से
= $ 2 से
खिसक जाना
खिसक जाना
फ़ाइलों = "$ @"
अगर टेस्ट -z "$" से -o -z "$" से -o -z "$ फाइलें"
फिर
    प्रतिध्वनि "उपयोग: $ 0 (फ़ाइल) *"
    इको "उदाहरण: $ 0 server1 server2 / usr / bin / myapp"
    बाहर निकलें 1
फाई

read -s -p "पासवर्ड दर्ज करें:" sudopassword
गूंज ""
temp1 = $ (mktemp)
temp2 = $ (mktemp)
(गूंज "$ sudopassword"; गूंज "$ sudopassword" | ssh $ from sudo -S tar c -P -C / $ files 2> $ temp1) | ssh $ to sudo -S tar x -v -P -C / 2 > $ temp2
sourceres = $ {PIPESTATUS [0]}
अगर [$? -एक 0-$ $ खटास -एक 0]
फिर
    गूंज "विफलता!" > और 2
    गूंज "आउटपुट से $:"> और 2
    बिल्ली $ temp1> & 2
    इको ""> और 2
    गूंज "$ आउटपुट के लिए:"> और 2
    बिल्ली $ temp2> & 2
    रेस = 1
फाई

rm $ temp1 $ temp2
बाहर निकलें $ Res

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

0

यहां विली व्हीलर के उत्तर का एक संशोधित संस्करण है जो फ़ाइल को टार के माध्यम से स्थानांतरित करता है, लेकिन रिमोट होस्ट पर sudo को पासवर्ड पास करने का भी समर्थन करता है।

(stty -echo; read passwd; stty echo; echo $passwd; tar -cz foo.*) \
  | ssh remote_host "sudo -S bash -c \"tar -C /var/www/ -xz; echo\""

थोड़ा अतिरिक्त जादू यहाँ -So विकल्प के लिए है। सुडो मैन पेज से:

-S, --stdin मानक त्रुटि का संकेत लिखें और टर्मिनल डिवाइस का उपयोग करने के बजाय मानक इनपुट से पासवर्ड पढ़ें। पासवर्ड को एक नए वर्ण द्वारा अनुसरण किया जाना चाहिए।

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

आप देखेंगे कि मैंने शीघ्र छापने के लिए -p विकल्प के साथ 'रीड' निष्पादित नहीं किया था। इसका कारण यह है कि sudo से पासवर्ड प्रॉम्प्ट ssh के माध्यम से हमारे इंटरेक्टिव शेल के stderr में आसानी से वापस चला जाता है। आपको आश्चर्य हो सकता है कि "सुडो को कैसे अंजाम दिया जाता है, यह हमारे पाइप के दाईं ओर ssh के अंदर चल रहा है?" जब हम कई कमांड निष्पादित करते हैं और एक के आउटपुट को दूसरे में पाइप करते हैं, तो मूल शेल (इस मामले में इंटरेक्टिव शेल) प्रत्येक कमांड को पिछले निष्पादित करने के तुरंत बाद अनुक्रम में निष्पादित करता है। जैसा कि एक पाइप के पीछे प्रत्येक कमांड को निष्पादित किया जाता है पैरेंट शेल संलग्न करता है (रीडायरेक्ट) बाएं-हाथ की तरफ स्टडआउट दाएं-हाथ की तरफ। आउटपुट तब इनपुट बन जाता है क्योंकि यह प्रक्रियाओं से गुजरता है।

$ (stty -echo; read passwd; stty echo; echo $passwd; tar -cz foo.*) | ssh 
remote_host "sudo -S bash -c \"tar -C /var/www/ -xz; echo\""
[sudo] password for bruce: 
[1]+  Stopped                 ( stty -echo; read passwd; stty echo; echo 
$passwd; tar -cz foo.* ) | ssh remote_host "sudo -S bash -c \"tar -C 
/var/www/ -xz; echo\""

$ pstree -lap $$
bash,7168
  ├─bash,7969
  ├─pstree,7972 -lap 7168
  └─ssh,7970 remote_host sudo -S bash -c "tar -C /var/www/ -xz; echo"`

हमारा इंटरेक्टिव शेल PID 7168 है, हमारा सबस्क्रिप्शन PID 7969 है और हमारी ssh प्रक्रिया PID 7970 है।

एकमात्र दोष यह है कि रीड इनपुट को स्वीकार करेगा इससे पहले कि सूडो के पास वापस भेजने का समय है, यह शीघ्र है। एक तेज़ कनेक्शन और तेज़ दूरस्थ होस्ट पर आप इसे नोटिस नहीं करेंगे, लेकिन यदि धीमा है तो आप इसे देख सकते हैं। कोई भी देरी शीघ्र में प्रवेश करने की क्षमता को प्रभावित नहीं करेगी; आपके द्वारा लिखना प्रारंभ करने के बाद यह बस दिखाई दे सकता है।

नोट मैंने केवल डेमो के लिए अपने स्थानीय मशीन में "रिमोट_होस्ट" के लिए एक होस्ट फ़ाइल प्रविष्टि जोड़ी है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.