كيف أستخدم sudo لإعادة توجيه الإخراج إلى موقع ليس لدي إذن بالكتابة إليه؟

StackOverflow https://stackoverflow.com/questions/82256

سؤال

لقد تم منحي حق الوصول إلى Sudo في أحد صناديق RedHat linux للتطوير، ويبدو أنني أجد نفسي في كثير من الأحيان بحاجة إلى إعادة توجيه الإخراج إلى موقع لا أتمكن عادةً من الوصول إليه للكتابة.

المشكلة هي أن هذا المثال المفتعل لا يعمل:

sudo ls -hal /root/ > /root/test.out

أتلقى الرد فقط:

-bash: /root/test.out: Permission denied

كيف يمكنني الحصول على هذا للعمل؟

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

المحلول

الأمر الخاص بك لا يعمل لأن عملية إعادة التوجيه تتم بواسطة الصدفة الخاصة بك والتي ليس لديها إذن بالكتابة إليها /root/test.out.إعادة توجيه الإخراج ليس يؤديها سودو.

هناك حلول متعددة:

  • قم بتشغيل Shell باستخدام sudo وأعطي الأمر له باستخدام الأمر -c خيار:

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • قم بإنشاء برنامج نصي بأوامرك وقم بتشغيل هذا البرنامج النصي باستخدام sudo:

    #!/bin/sh
    ls -hal /root/ > /root/test.out
    

    يجري sudo ls.sh.انظر ستيف بينيت إجابة إذا كنت لا تريد إنشاء ملف مؤقت.

  • إطلاق قذيفة مع sudo -s ثم قم بتشغيل الأوامر الخاصة بك:

    [nobody@so]$ sudo -s
    [root@so]# ls -hal /root/ > /root/test.out
    [root@so]# ^D
    [nobody@so]$
    
  • يستخدم sudo tee (إذا كان عليك الهروب كثيرًا عند استخدام -c خيار):

    sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
    

    إعادة التوجيه إلى /dev/null هناك حاجة للتوقف قمزة من الإخراج إلى الشاشة.ل ألحق بدلاً من الكتابة فوق ملف الإخراج (>>)، يستخدم tee -a أو tee --append (الأخير خاص بـ ملفات جنو الأساسية).

شكرا اذهب الى دينار, آدم ج.فورستر و جوناثان للحلول الثاني والثالث والرابع.

نصائح أخرى

لقد اقترح شخص ما هنا للتو وضع نقطة الإنطلاق:

sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null

يمكن استخدام هذا أيضًا لإعادة توجيه أي أمر إلى دليل لا يمكنك الوصول إليه.إنه يعمل لأن برنامج Tee هو برنامج "صدى لملف" بشكل فعال، وإعادة التوجيه إلى /dev/null هي إيقاف إخراجه أيضًا إلى الشاشة لإبقائه كما هو في المثال الأصلي المبتكر أعلاه.

الحيلة التي اكتشفتها بنفسي كانت

sudo ls -hal /root/ | sudo dd of=/root/test.out

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

sudo command > /some/file.log
`-----v-----'`-------v-------'
   command       redirection

الطرق المعتادة لتجاوز ذلك هي:

  • قم بلف الأوامر في البرنامج النصي الذي تتصل به ضمن Sudo.

    إذا تغيرت الأوامر و/أو السجل ، فيمكنك جعل البرنامج النصي يأخذ هذه الوسيطات.على سبيل المثال:

    sudo log_script command /log/file.txt
    
  • استدعاء قذيفة وتمرير سطر الأوامر كمعلمة مع -c

    وهذا مفيد بشكل خاص للأوامر المركبة لمرة واحدة.على سبيل المثال:

    sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
    

اختلاف آخر حول الموضوع:

sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF

أو بالطبع:

echo 'ls -hal /root/ > /root/test.out' | sudo bash

لديهم ميزة (صغيرة) وهي أنك لا تحتاج إلى تذكر أي حجج لها sudo أو sh/bash

توضيح قليلاً عن سبب تفضيل خيار الإنطلاق

بافتراض أن لديك الإذن المناسب لتنفيذ الأمر الذي ينشئ المخرجات، إذا قمت بتوجيه مخرجات الأمر إلى Tee، فأنت تحتاج فقط إلى رفع امتيازات Tee باستخدام Sudo وTe المباشر للكتابة (أو الإلحاق) بالملف المعني.

في المثال الوارد في السؤال الذي يعني:

ls -hal /root/ | sudo tee /root/test.out

للحصول على بعض الأمثلة العملية الإضافية:

# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts

# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4

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

إنها فكرة جيدة أن يتم ذلك بهذه الطريقة لأن الأمر الذي ينشئ الإخراج لا يتم تنفيذه بامتيازات مرتفعة.لا يبدو أن الأمر يهم هنا مع echo ولكن عندما يكون الأمر المصدر عبارة عن برنامج نصي لا تثق به تمامًا، فهو أمر بالغ الأهمية.

لاحظ أنه يمكنك استخدام الخيار -a لإلحاق الإلحاق (مثل >>) إلى الملف الهدف بدلاً من الكتابة فوقه (مثل >).

اجعل Sudo يقوم بتشغيل Shell، مثل هذا:

sudo sh -c "echo foo > ~root/out"

الطريقة التي سأتعامل بها مع هذه المشكلة هي:

إذا كنت بحاجة إلى كتابة/استبدال الملف:

echo "some text" | sudo tee /path/to/file

إذا كنت بحاجة إلى إلحاق الملف:

echo "some text" | sudo tee -a /path/to/file

ماذا عن كتابة السيناريو؟

اسم الملف:com.myscript

#!/bin/sh

/bin/ls -lah /root > /root/test.out

# end script

ثم استخدم Sudo لتشغيل البرنامج النصي:

sudo ./myscript

سأفعل ذلك بهذه الطريقة:

sudo su -c 'ls -hal /root/ > /root/test.out'

عندما يتعين علي أن أفعل شيئًا كهذا، فإنني أصبح جذرًا:

# sudo -s
# ls -hal /root/ > /root/test.out
# exit

ربما لا تكون هذه هي الطريقة الأفضل، لكنها تعمل.

لا أقصد التغلب على حصان ميت، ولكن هناك الكثير من الإجابات هنا التي يمكن استخدامها tee, ، مما يعني أنه يتعين عليك إعادة التوجيه stdout ل /dev/null إلا إذا كنت تريد رؤية نسخة على الشاشة.الحل الأبسط هو الاستخدام فقط cat مثله:

sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"

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

ويستند هذا على الإجابة التي تنطوي على tee.لتسهيل الأمور، كتبت نصًا صغيرًا (أسميه suwrite) وأدخله /usr/local/bin/ مع +x إذن:

#! /bin/sh
if [ $# = 0 ] ; then
    echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
    exit 1
fi
for arg in "$@" ; do
    if [ ${arg#/dev/} != ${arg} ] ; then
        echo "Found dangerous argument ‘$arg’. Will exit."
        exit 2
    fi
done
sudo tee "$@" > /dev/null

كما هو مبين في الاستخدام في الكود، كل ما عليك فعله هو توجيه الإخراج إلى هذا البرنامج النصي متبوعًا باسم الملف المطلوب الذي يمكن للمستخدم المتميز الوصول إليه وسيطالبك تلقائيًا بكلمة المرور الخاصة بك إذا لزم الأمر (نظرًا لأنه يتضمن sudo).

echo test | suwrite /root/test.txt

لاحظ أنه نظرًا لأن هذا غلاف بسيط لـ tee, ، وسوف يقبل أيضًا المحملة -a خيار الإلحاق، كما يدعم الكتابة إلى ملفات متعددة في نفس الوقت.

echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt

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

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

إذا لم يكن الأمر كذلك، فربما يمكنك كتابة نص bash:

cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out 

يضعط كنترول + د :

chmod a+x myscript.sh
sudo myscript.sh

نأمل أن يساعد.

sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top