sudo echo“ something” >> / etc / privilegedFile ไม่ทำงาน


586

นี่เป็นคำถามที่ค่อนข้างง่ายอย่างน้อยก็น่าจะเป็นไปได้เกี่ยวกับการอนุญาต sudo ใน Linux

มีหลายครั้งที่ฉันแค่อยากจะต่อท้าย/etc/hostsไฟล์หรือไฟล์ที่คล้ายกัน แต่ท้ายที่สุดก็ไม่สามารถทำได้เพราะทั้งคู่>และ>>ไม่ได้รับอนุญาตแม้แต่กับรูท

มีบางประการเพื่อให้งานนี้ได้โดยไม่ต้องsuหรือsudo suเข้าสู่ราก?

คำตอบ:


855

ใช้หรือtee --appendtee -a

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list

ตรวจสอบให้แน่ใจเพื่อหลีกเลี่ยงคำพูดในคำพูด

เพื่อหลีกเลี่ยงการพิมพ์ข้อมูลกลับไปที่คอนโซลเปลี่ยนเส้นทางเอาต์พุตไปยัง / dev / null

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list > /dev/null

จำเกี่ยวกับธง( -a/ --append)! เพียงแค่teeทำงานเหมือน>และจะเขียนทับไฟล์ของคุณ tee -aทำงานเหมือน>>และจะเขียนเมื่อสิ้นสุดไฟล์


3
ฉันชอบอันนี้มาก มันเป็นวิธีที่ง่ายที่สุด (และทำให้ฉันต้องคิดเรื่องทีออฟซึ่งมีประโยชน์ในสถานการณ์อื่น ๆ ด้วย)
Joachim Sauer

5
ฉันเห็นด้วย. ดูเหมือนว่าจะเริ่มต้นใหม่ด้วยเช่นกันโดยเฉพาะอย่างยิ่งเมื่อมีโอกาสทำสิ่งต่าง ๆ กับสภาพแวดล้อม ฯลฯ
Sam Brightman

39
สิ่งสำคัญที่ควรทราบ: อย่าลืม -a! แค่คิดว่าecho 'tmpfs /tmp tmpfs defaults 0 0' | sudo tee /etc/fstabจะทำอะไร
mic_e

21
ภายใต้ OS X นี้ควรจะเป็นแทนtee -a tee --append
knite

26
สำหรับผู้ที่ไม่เข้าใจสิ่งที่ @mic_e พูดว่า: หากไม่มีการ-a--appendตั้งค่าสถานะ( ) คำสั่งจะเขียนทับไฟล์ทั้งหมดด้วยสตริงที่กำหนดแทนที่จะต่อท้ายไฟล์
totymedli

314

ปัญหาคือเชลล์ทำการเปลี่ยนเส้นทางเอาต์พุตไม่ใช่ sudo หรือ echo ดังนั้นสิ่งนี้จะถูกดำเนินการในฐานะผู้ใช้ปกติของคุณ

ลองตัวอย่างโค้ดต่อไปนี้:

sudo sh -c "echo 'something' >> /etc/privilegedfile"

"ขอบเขตการอนุญาต sudo" คืออะไร มันเป็นแค่เปลือกที่แยกผู้ประกอบการเปลี่ยนเส้นทางที่มีความสำคัญสูงกว่าคำสั่งสำหรับเหตุผลที่ชัดเจน
Vinko Vrsalovic

1
ทั้งนี้ขึ้นอยู่กับคุณshก้องสามารถตีความลำดับหนีเช่น\tราคาเดียวภายใน คุณสามารถใช้printf %s 'something'แทน
Lri

การใช้ทีเป็นที่นิยมมากขึ้นและเข้ากันได้ดีกับ distros รุ่นใหม่
Eduardo B.

1
นี่เป็นสิ่งเดียวที่ทำงานตามที่เป็นอยู่เป็นคำสั่ง SSH ซึ่งสามารถดำเนินการบนโหนดระยะไกล
Duncan Lock

ฉันเห็นด้วยกับโพสต์อื่น ๆ ที่นี่ สิ่งนี้ใช้เชลล์และเชลล์เท่านั้นดังนั้นจึงไม่จำเป็นต้องใช้โปรแกรมอื่นเช่น tee ใช่ฉันรู้ว่ามีการติดตั้งเสื้อยืดแล้ว แต่อาจไม่ได้ขึ้นอยู่กับว่าคุณใช้ดิสทริบิวเตอร์อะไรเช่นกระดูกเปลือย ฉันชอบที่คุณมีตัวเลือกเปลือกเกินไป: sudo /bin/bash -c "echo 'fs.inotify.max_user_watches = 524288' > /etc/sysctl.d/60-golang-inotify.conf"ตัวอย่างเช่น
Ligemer

35

ปัญหาคือมันเป็นเปลือกของคุณที่จัดการการเปลี่ยนเส้นทาง; กำลังพยายามเปิดไฟล์โดยใช้สิทธิ์ของคุณไม่ใช่ขั้นตอนที่คุณใช้ภายใต้ sudo

ใช้บางสิ่งเช่นนี้บางที:

sudo sh -c "echo 'something' >> /etc/privilegedFile"

@GordonSun เป็นเพราะsudo(เพื่อเหตุผลด้านความปลอดภัย) ไม่เผยแพร่สภาพแวดล้อมไปยังกระบวนการย่อย คุณสามารถใช้sudo -Eเพื่อหลีกเลี่ยงข้อ จำกัด นี้
arielf

1
@GordonSun ใช่แล้วฉันจะไม่เข้าใจว่าทำไมคุณถึงพูดประโยคนี้ซ้ำไปเรื่อย ๆ ! หากคุณsudo sh -c "echo 'something' >> $FILENAME"ใช้เครื่องหมายอัญประกาศคู่สิ่งนี้จะใช้ได้ - การแทนที่ตัวแปรทำโดยเชลล์ด้านนอกไม่ใช่เชลล์ sudoed
Nadav Har'El


13

การทำ

sudo sh -c "echo >> somefile"

ควรทำงาน. ปัญหาคือว่า> และ >> ได้รับการจัดการโดยเชลล์ของคุณไม่ใช่โดยคำสั่ง "sudoed" ดังนั้นการอนุญาตเป็นสิทธิ์ของคุณไม่ใช่สิทธิ์ของผู้ใช้ที่คุณ "เข้าสู่ sudoing"


9

ฉันอยากทราบว่าคุณสามารถอ้าง heredoc (สำหรับบล็อกขนาดใหญ่):

sudo bash -c "cat <<EOIPFW >> /etc/ipfw.conf
<?xml version=\"1.0\" encoding=\"UTF-8\"?>

<plist version=\"1.0\">
  <dict>
    <key>Label</key>
    <string>com.company.ipfw</string>
    <key>Program</key>
    <string>/sbin/ipfw</string>
    <key>ProgramArguments</key>
    <array>
      <string>/sbin/ipfw</string>
      <string>-q</string>
      <string>/etc/ipfw.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true></true>
  </dict>
</plist>
EOIPFW"

1
วิธีนี้ใช้งานได้ดียกเว้นว่าราคาที่ฝังไว้อาจจำเป็นต้องใช้ Escape \
N Jones เมื่อ

ค่อนข้างถูก @Nones! ฉันจะแก้ไขคำตอบของฉัน (อย่างไรก็ตามโปรดทราบว่าการไม่ทำเช่นนี้จะทำให้แถบภายใน"แต่ไม่ทำให้คำสั่งล้มเหลว)
msanford

8

ในทุบตีคุณสามารถใช้teeร่วมกับ> /dev/nullเพื่อให้ stdout สะอาด

 echo "# comment" |  sudo tee -a /etc/hosts > /dev/null

4

ใช้คำตอบของ Yooใส่สิ่งนี้ลงใน~/.bashrc:

sudoe() {
    [[ "$#" -ne 2 ]] && echo "Usage: sudoe <text> <file>" && return 1
    echo "$1" | sudo tee --append "$2" > /dev/null
}

ตอนนี้คุณสามารถเรียกใช้ sudoe 'deb blah # blah' /etc/apt/sources.list


แก้ไข:

เวอร์ชันที่สมบูรณ์ยิ่งขึ้นซึ่งอนุญาตให้คุณไพพ์อินพุตหรือเปลี่ยนทิศทางจากไฟล์และรวมถึง-aสวิตช์เพื่อปิดการต่อท้าย (ซึ่งจะเปิดตามค่าดีฟอลต์):

sudoe() {
  if ([[ "$1" == "-a" ]] || [[ "$1" == "--no-append" ]]); then
    shift &>/dev/null || local failed=1
  else
    local append="--append"
  fi

  while [[ $failed -ne 1 ]]; do
    if [[ -t 0 ]]; then
      text="$1"; shift &>/dev/null || break
    else
      text="$(cat <&0)"
    fi

    [[ -z "$1" ]] && break
    echo "$text" | sudo tee $append "$1" >/dev/null; return $?
  done

  echo "Usage: $0 [-a|--no-append] [text] <file>"; return 1
}

2

คุณสามารถใช้spongeจากmoreutilsแพ็คเกจและไม่จำเป็นต้องเปลี่ยนเส้นทางเอาต์พุต (เช่นไม่มีteeเสียงรบกวนเพื่อซ่อน):

echo 'Add this line' | sudo sponge -a privfile

0

โดยใช้sed -i กับ $ a , คุณสามารถต่อท้ายข้อความ, ประกอบด้วยทั้งตัวแปรและอักขระพิเศษ, หลังบรรทัดสุดท้าย

ตัวอย่างเช่นการเพิ่ม $ NEW_HOST ด้วย $ NEW_IP ไปยัง / etc / hosts:

sudo sed -i "\$ a $NEW_IP\t\t$NEW_HOST.domain.local\t$NEW_HOST" /etc/hosts

ตัวเลือก sed อธิบาย:

  • -iสำหรับในสถานที่
  • $สำหรับบรรทัดสุดท้าย
  • สำหรับผนวก


0

วิธีการเกี่ยวกับ:
echo text | sudo dd status = none of = privilegedfile
ฉันต้องการเปลี่ยน / proc / sys / net / ipv4 / tcp_rmem
ฉันทำ:
sudo dd status = ไม่มีของ = / proc / sys / net / ipv4 / tcp_rmem <<< "4096 131072 1024000"
กำจัดเสียงสะท้อนด้วยเอกสารบรรทัดเดียว


1
โปรดใช้เวลาสักครู่เพื่ออ่านผ่านความช่วยเหลือแก้ไขในศูนย์ช่วยเหลือ การจัดรูปแบบใน Stack Overflow นั้นแตกต่างจากไซต์อื่น ๆ
Dharman

-1

สิ่งนี้ใช้ได้กับฉัน: คำสั่งดั้งเดิม

echo "export CATALINA_HOME="/opt/tomcat9"" >> /etc/environment

คำสั่งการทำงาน

echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment

1
tee -aควรจะเป็น เพียงแค่teeจะเขียนทับไฟล์!
codeforester

-6

คุณสามารถเปลี่ยนความเป็นเจ้าของไฟล์แล้วเปลี่ยนกลับหลังจากใช้cat >>เพื่อต่อท้ายได้หรือไม่?

sudo chown youruser /etc/hosts  
sudo cat /downloaded/hostsadditions >> /etc/hosts  
sudo chown root /etc/hosts  

สิ่งนี้เหมาะกับคุณหรือไม่


4
Chown เป็นคำสั่งทำลายที่จะใช้ หากตัวจัดการการกำหนดค่าใช้เพื่ออัปเดต / etc / hosts ทันใด / etc / hosts จะเป็นของผู้ใช้ config และไม่ใช่รูท ซึ่งอาจนำไปสู่กระบวนการอื่น ๆ ที่ไม่มีสิทธิ์เข้าถึง / etc / hosts จุดรวมของ sudo คือการหลีกเลี่ยงสิ่งที่ล็อกอินเข้าสู่ root และผ่าน sudoers ข้อ จำกัด เพิ่มเติมสามารถซ้อนกันได้เช่นกัน
David
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.