මට ලිවීමට අවසර නොමැති ස්ථානයකට ප්‍රතිදානය හරවා යැවීමට සුඩෝ භාවිතා කරන්නේ කෙසේද?


901

අපගේ එක් සංවර්ධන රෙඩ්හැට් ලිනක්ස් පෙට්ටියකට මට සුඩෝ ප්‍රවේශය ලබා දී ඇති අතර, සාමාන්‍යයෙන් මට ලිඛිත ප්‍රවේශයක් නොමැති ස්ථානයකට ප්‍රතිදානය හරවා යැවීමට බොහෝ විට අවශ්‍ය බව මට පෙනේ.

කරදරය නම්, මෙම ව්‍යාජ උදාහරණය ක්‍රියා නොකරයි:

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

මට ප්‍රතිචාරය ලැබුණේ:

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

මෙය ක්‍රියාත්මක කිරීමට මට හැක්කේ කෙසේද?


1
chmod u + w ගොනු නාමය භාවිතා කරන්න
Szabolcs Dombi

@DombiSzabolcs ඔබ යෝජනා කරන්නේ මම මුලින්ම ගොනුව sudo ලෙස නිර්මාණය කරන ලෙසයි, පසුව මට අවසර දෙන්න? හොඳ අදහස.
ජොනතන්

බොහෝ අවස්ථාවන්හිදී ඔබ මෙහි පැමිණෙන්නේ "මට අවසර ප්‍රතික්ෂේප වන්නේ ඇයි?" සමහර විට පිළිතුර නම් ඔබට ගොනුවක් සෑදිය යුතු බවයි root(එම අවස්ථාවේ දී පිළිතුරු කියවීමට ඉදිරියට යන්න) නමුත් බොහෝ විට ඔබ ඔබ මෙන් වෙනත් තැනක ගොනුව සෑදිය යුතුය.
ත්‍රිත්ව

1
මෙම පිළිතුරු සමඟ පොරබදීමෙන් පසු මම අවසාන වරට තාවකාලික ගොනුවකට හරවා එය ගමනාන්තයට ගෙන යාමට තෝරා ගතිමි.
TingQian LI

Answers:


1260

ඔබේ විධානය ක්‍රියාත්මක නොවන්නේ නැවත යොමු කිරීම ඔබේ කවචය මඟින් ලිවීමට අවසර නොමැති නිසාය /root/test.out. ප්‍රතිදානයේ යළි හරවා යැවීම 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නතර කිරීමට අවශ්ය ටී තිරය outputting සිට. කිරීමට ඇතුලත් වෙනුවට ප්රතිදානය ගොනු මත ලියන්නේ ( >>), භාවිතය tee -aහෝ tee --append(අන්තිම එක විශේෂිත වේ GNU coreutils ).

දෙවන, තෙවන සහ සිව්වන විසඳුම් සඳහා ජේඩී , ඇඩම් ජේ. ෆෝස්ටර් සහ ජොනතන් වෙත ස්තූතියි .


1
STDERR සහ STDOUT වෙන වෙනම හරවා යැවිය හැකි ආකාරය ඔබට පවසන විශිෂ්ට පිළිතුරක් ඇත: stackoverflow.com/questions/692000/… ... මූලික වශයෙන්perl -e 'print "STDIN\n"; print STDERR "STDERR\n"; ' > >( tee stdout.log ) 2> >( tee stderr.log >&2 )
errant.info

2
ෂෙල්ඩ් අවුට් විධානයෙහි විචල්‍යයන් භාවිතා කිරීම සඳහා ඔබට 'sudo -E ...' කිරීමට අවශ්‍ය වනු ඇත (මෙය ස්ක්‍රිප්ට් එකක භාවිතා කරන විට, උදාහරණයක් ලෙස).
උර්හික්සිදූර්

3
ප්‍රතිදානය තිරයට ප්‍රතිරාවය කිරීම හානිකර නොවන බොහෝ අවස්ථාවන්හිදී ටී ප්‍රතිදානය / dev / null වෙත හරවා යැවීම අවශ්‍ය නොවේ. නිදසුනක් ලෙස, සාමාන්‍ය විධාන හෝ කුඩා පෙළ ලිපිගොනු වල ප්‍රතිදානය සමඟ කටයුතු කරන විට.
thomasrutter

108

මෙහි කවුරුහරි යෝජනා කර ඇත්තේ සුඩෝ කිරීම සඳහා ය:

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

ඕනෑම විධානයක් ඔබට පිවිසිය නොහැකි නාමාවලියකට හරවා යැවීමටද මෙය භාවිතා කළ හැකිය. එය ක්‍රියාත්මක වන්නේ ටී වැඩසටහන effectively ලදායී ලෙස “ගොනුවකට දෝංකාර දෙන” වැඩසටහනක් වන අතර / dev / null වෙත හරවා යැවීම යනු එය තිරයට ප්‍රතිදානය කිරීම නැවැත්වීමයි.


5
බොහෝ අවස්ථාවන්හීදී, සාමාන්‍ය පරිශීලකයාට විධානය ක්‍රියාත්මක කිරීම සඳහා ප්‍රමිති තිබේ නම් සහ අපේක්ෂිත ප්‍රතිදාන ගොනුවට "පමණක්" ලිවිය නොහැකි නම්, පළමු sudo(එනම්, විධානය සඳහාම) මඟ
හැරිය

84

මා විසින්ම හදුනාගත් උපක්‍රමයක්

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

16
sudo ddsudo tee /root/file > /dev/nullඉහත උදාහරණ වලට වඩා හොඳයි !
kristianlm

14
dd යනු අමුතු අපැහැදිලි විධානයක් නොවේ. බ්ලොක් උපාංග දෙකක් අතර බෆරින් සමඟ විශාල දත්ත ප්‍රමාණයක් පිටපත් කිරීමට ඔබට අවශ්‍ය විටෙක එය භාවිතා වේ. වාක්‍ය ඛණ්ඩය සැබවින්ම සරල ය, ddවිධාන නාමය, ප්‍රතිදාන ලිපිගොනු යනු කුමක්දැයි of=/root/test.outපවසන තර්කයයි dd.
rhlee

14
@steve ඔබ එය කුමක්දැයි ඉගෙන ගන්නා තෙක් සියල්ල 'අපැහැදිලි' ය. ofඅදහස් ප්රතිදානය ගොනු හා dd(බොහෝ තැටි රූප ලිවීම සඳහා) Linux සහ OSX එකක් දෙකම භාවිතා ඉතා ජනප්රිය මෙවලමකි. මෙය නිසැකවම පිළිවෙලකි.
blockloop

12
ddබොහෝ විට teeමෙහි සමානවම ප්‍රයෝජනවත් වේ . මෙම අවස්ථා දෙකෙහිම ඔබ පොදු, සුප‍්‍රසිද්ධ විධානයක් භාවිතා කරන්නේ, එහි මුල් අපේක්ෂිත අරමුණට වඩා තරමක් වෙනස් වුවත්, තවමත් හොඳින් දන්නා සහ හොඳින් ලේඛනගත කර ඇති අරමුණක් සඳහා ය. ddවිශාල දත්ත ප්‍රමාණයක් පිටපත් කිරීමට හොඳ වුවත් , එය කුඩා ප්‍රමාණවලින් උරා ගන්නේ නැත. ප්‍රතිදානය සම්මත නිමැවුමට දෝංකාර නොදීමෙන් මෙහි වාසිය ඇත.
thomasrutter

27
ඔබ වචන ටයිප් කරන විට sudo ddඊළඟ එකිනෙකාට, ඔබ ඉතා, කරන්න ඕන ඉතා වග අනුගමනය කරන තර්ක (විශේෂයෙන්ම එහි සම්මත නොවන කාරක රීති සලකා) නිවැරදි බව. ඔවුන් එය "තැටි විනාශ
කරන්නා

47

ගැටළුව වන්නේ විධානය යටතේ ක්‍රියාත්මක වීමයි sudo, නමුත් යළි හරවා යැවීම ඔබේ පරිශීලකයා යටතේ ක්‍රියාත්මක වේ. මෙය සිදු කරනු ලබන්නේ කවචය වන අතර ඔබට ඒ පිළිබඳව කළ හැක්කේ ඉතා අල්පයකි.

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

මෙය මඟ හැරීමේ සාමාන්‍ය ක්‍රම:

  • සුඩෝ යටතේ ඔබ අමතන ස්ක්‍රිප්ට් එකක විධාන ඔතා.

    විධාන සහ / හෝ ලොග් ගොනුව වෙනස් වුවහොත්, ඔබට ස්ක්‍රිප්ටය මේවා තර්ක ලෙස ගත හැකිය. උදාහරණයක් වශයෙන්:

    sudo log_script command /log/file.txt
    
  • කවචයක් අමතා විධාන රේඛාව සමඟ පරාමිතියක් ලෙස සම්මත කරන්න -c

    එක් ඕෆ් සංයුක්ත විධාන සඳහා මෙය විශේෂයෙන් ප්‍රයෝජනවත් වේ. උදාහරණයක් වශයෙන්:

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

23

තේමාව පිළිබඳ තවත් වෙනස්කමක්:

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

හෝ ඇත්ත වශයෙන්ම:

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

ඔවුන් ඔබ වෙත කිසිදු තර්ක මතක තබා ගැනීමට අවශ්ය නැති බව ද (ඉතා කුඩා) වාසිය sudoහෝ sh/bash


20

ටී විකල්පය වඩාත් සුදුසු වන්නේ මන්ද යන්න පිළිබඳව ටිකක් පැහැදිලි කිරීම

ප්‍රතිදානය නිර්මාණය කරන විධානය ක්‍රියාත්මක කිරීමට ඔබට සුදුසු අවසරයක් ඇතැයි උපකල්පනය කරමින්, ඔබ ඔබේ විධානයේ ප්‍රතිදානය ටී වෙත නල කරන්නේ නම්, ඔබට අවශ්‍ය වන්නේ ටීගේ පුද්ගලිකත්වය සුඩෝ සහ සෘජු ටී සමඟ ඔසවා තැබීම පමණි.

ප්‍රශ්නයේ දක්වා ඇති උදාහරණයේ අර්ථය:

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 විකල්පය භාවිතා කළ හැකි බව සලකන්න >.


කණගාටුයි js3, නමුත් මෙය දැනටමත් යෝජනා කර ඇත (2008 දී) සහ දෙවන ඉහළම පිළිතුරෙහි වාඩි වී සිටී: stackoverflow.com/a/82553/6910
ජොනතන්

2
ඔබ හරි, ජොනතන්, මෙය වඩාත් සුදුසු විකල්පයක් වීමට හේතු පුළුල් කිරීමට මම මගේ පිළිතුර යාවත්කාලීන කරමි. ප්‍රයෝජනවත් ප්‍රතිපෝෂණයට ස්තූතියි.
jg3


11

මෙම ගැටලුව සම්බන්ධයෙන් මා යා යුතු ආකාරය:

ඔබට ගොනුව ලිවීමට / ප්‍රතිස්ථාපනය කිරීමට අවශ්‍ය නම්:

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

ඔබට ගොනුවට එකතු කිරීමට අවශ්‍ය නම්:

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

1
ඉහත පිළිතුරු වලට මෙය සැලකිය යුතු ලෙස වෙනස් වන්නේ කෙසේද?
ජොනතන්

2
එය "සැලකිය යුතු ලෙස වෙනස්" නොවේ, නමුත් එය ගොනුව ප්රතිස්ථාපනය කිරීම හා එකතු කිරීම අතර ඇති සුවිශේෂී භාවිතය පැහැදිලි කරයි.
jamadagni

1
මගේ වංචා පත්‍රයට පිටපත් කළ පිළිතුර මෙයයි.
මෝර්ටිමර් කැට්

5

පිටපතක් ලිවීම ගැන කුමක් කිව හැකිද?

ගොනු නාමය: myscript

#!/bin/sh

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

# end script

ස්ක්‍රිප්ට් ධාවනය කිරීමට sudo භාවිතා කරන්න:

sudo ./myscript

4

මට මේ වගේ දෙයක් කිරීමට සිදු වූ සෑම අවස්ථාවකම මම මූල බවට පත්වෙමි:

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

එය බොහෝ විට හොඳම ක්‍රමය නොවේ, නමුත් එය ක්‍රියාත්මක වේ.


4

මම එය මේ ආකාරයෙන් කරන්නෙමි:

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

2
ඔබට ෂෙල් එක පැහැදිලිව සඳහන් කිරීමට අවශ්‍ය නොවන බැවින් එය ඇත්තෙන්ම ටිකක් පිරිසිදු බව පෙනේ.
ස්ටීව් බෙනට්

1
එක් කුඩා අඩුපාඩුවක් නම් එය එක් අතිරේක ක්‍රියාවලියක් ක්‍රියාත්මක කිරීමයි ( su): $ sudo su -c 'pstree -sp $$ >/dev/fd/1' init(1)───gnome-terminal(6880)───bash(6945)───sudo(401)───su(402)───bash(410)───pstree(411)
pabouk

3

මිය ගිය අශ්වයෙකුට පහර දීමට අදහස් නොකරන්න, නමුත් මෙහි පිළිතුරු ඕනෑවටත් වඩා තිබේ tee, එයින් අදහස් කරන්නේ ඔබට පිටපතක් තිරය මත දැකීමට අවශ්‍ය නම් මිස ඔබ නැවත හරවා යැවිය stdoutයුතු /dev/nullබවයි.

සරල විසඳුමක් නම් මේ ආකාරයට භාවිතා කිරීමයි cat:

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

නැවත හරවා යැවීම උපුටා දැක්වීම් තුළට දමා ඇති ආකාරය සැලකිල්ලට ගන්න, එවිට එය sudoධාවනය වන එක වෙනුවට ආරම්භ කරන ලද කවචයකින් එය ඇගයීමට ලක් කෙරේ .


මෙය හොඳින් ක්‍රියාත්මක වේ. එයට එක් නිෂේධාත්මක ඡන්දයක් තිබුනේ මන්දැයි මට තේරෙන්නේ නැත. ඉහළට.
Teemu Leisti

4
මම හිතන්නේ එයට වඩා ආදරය නොලැබෙන නිසා එය වඩා හොඳ නොවේ sudo bash -c "ls -hal /root > /root/test.out". ටී භාවිතා කිරීම ෂෙල් එකක් අවශ්‍ය වන අතර බළලාට අවශ්‍ය නොවේ.
නික් රුසෝ

2

මෙය පදනම් වී ඇති පිළිතුර මත පදනම් වේ 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

කේතයේ USAGE හි පෙන්වා ඇති පරිදි , ඔබ කළ යුතුව ඇත්තේ මෙම ස්ක්‍රිප්ටයට ප්‍රතිදානය පයිප්ප කිරීමෙන් පසුව අපේක්ෂිත සුපර් යූසර් වෙත ප්‍රවේශ විය හැකි ගොනු නාමයක් වන අතර අවශ්‍ය නම් එය ස්වයංක්‍රීයව ඔබගේ මුරපදය ඉල්ලා සිටිනු ඇත (එයට ඇතුළත් බැවින් 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/මෙම පිටුවේ එක් අදහස් දැක්වීමක සඳහන් කර ඇති උපාංගවලට ලිවීමට එරෙහිව සරල ආරක්ෂාවක් ද එයට ඇත .


1

සමහර විට ඔබට සමහර වැඩසටහන් / මාර්ග වලට පමණක් සුඩෝ ප්‍රවේශය ලබා දී තිබේද? එවිට ඔබට අවශ්‍ය දේ කිරීමට ක්‍රමයක් නොමැත. (ඔබ එය කෙසේ හෝ හැක් නොකරන්නේ නම්)

එය එසේ නොවේ නම් සමහර විට ඔබට bash ස්ක්‍රිප්ට් ලිවිය හැකිය:

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

ctrl+ ඔබන්න d:

chmod a+x myscript.sh
sudo myscript.sh

එය උපකාරී වේ යැයි සිතමි.


1
sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  

1
ඔබට sudoකෙසේ හෝ තිබේ නම් , atප්‍රයෝජනවත් හෝ අවශ්‍ය නොවේ. sudo sh -c 'echo test >/tmp/test.out'එය වඩාත් කාර්යක්ෂමව හා අලංකාර ලෙස සිදු කරයි (නමුත් තවමත් rootඑම වරප්‍රසාදය අවශ්‍ය නොවන දේවල් ඔබ ක්‍රියාත්මක කරන දෝෂයෙන් පීඩා විඳිති ; සාමාන්‍යයෙන් ඔබට හැකි විට වරප්‍රසාදිත විධානයන් මග හැරිය යුතුය).
ත්‍රිත්ව
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.