อ่านและยืนยันเชลล์สคริปต์ก่อนทำการไพพ์จาก curl ถึง sh (curl -s [url] | sh)


11

เมื่อใดก็ตามที่ฉันต้องเรียกใช้งานเชลล์สคริปต์จากเว็บcurl -s [url] | shฉันจะเปิดurlในเว็บเบราว์เซอร์ก่อนเพื่อให้แน่ใจว่าสคริปต์นั้นไม่เป็นอันตรายและปลอดภัยในการทำงาน

ฉันจำได้ว่าเห็นเคล็ดลับบรรทัดคำสั่งที่ทำให้สามารถอ่านสคริปต์จากบรรทัดคำสั่งแล้วยืนยันการทำงานหลังจากอ่านสคริปต์ ถ้าฉันจำได้ถูกต้องมันดูเหมือนว่าcurl -s [url] | something...here | shและไม่ต้องการติดตั้งซอฟต์แวร์ใด ๆ

ไม่มีใครรู้เคล็ดลับนี้

คำตอบ:


5

มียูทิลิตี้ที่moreutilsเรียกvipeว่าแสดง stdin ในตัวแก้ไขซึ่งคุณสามารถเปิดเผยและแก้ไขไฟล์ก่อนที่มันจะถูกส่งต่อไปยัง stdout

หากคุณไม่ต้องการติดตั้งmoreutilsคุณสามารถทำสิ่งที่คล้ายกันได้ดังนี้:

file=$(mktemp); curl -s "$url" > $file; $EDITOR $file; sh $file; rm $file

mktempอยู่ในcoreutilsและมีโอกาสมากที่ติดตั้งอยู่บนระบบของคุณ


2

ฉันไม่สามารถนึกถึงยูทิลิตี้เดียวที่จะทำสิ่งที่คุณอธิบายได้ แต่มันก็ง่ายพอที่จะทำให้มันเป็นตัวอย่างของเชลล์

script=$(curl -s "$url")
printf "%s\nDo you want to run this script? [yN]" "$script"
read line
case $line in
  [Yy]|[Yy][Ee][Ss]) sh -c "$script";;
esac

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

script_file=$(mktemp)
curl -s "$url" | tee "$script_file"
printf "Do you want to run this script? [yN]"
read line
case $line in
  [Yy]|[Yy][Ee][Ss]) sh "$script_file";;
esac
rm "$script_file"

$()ควรจะยกมาในบรรทัดแรก นอกจากนี้สิ่งนี้จะลบอักขระ NUL ในอินพุตซึ่งอาจเป็นอันตรายถึงชีวิต (ตัวอย่างเช่นในกรณีของสคริปต์ที่แตกไฟล์ด้วยตนเอง)
l0b0

1
@ l0b0 คุณไม่จำเป็นต้องไปอ้างในการกำหนดแม้ว่ามันจะเป็นเนื้อหารูปแบบที่ดี ไบต์ที่ไม่มีค่าจะสูญหายไปเช่นเดียวกับการขึ้นบรรทัดใหม่ หากคุณกำลังจะรวมการเก็บถาวรในเชลล์สคริปต์ผมแนะนำให้ใช้การเข้ารหัสข้อความเช่น base64
Gilles 'SO- หยุดความชั่วร้าย'

คะแนนที่ถูกต้องทั้งหมดตามปกติ +1
l0b0

@ l0b0 ในความคิดที่สองในขณะที่มันค่อนข้างเสี่ยงต่อความเสี่ยงนี่เป็นกรณีการใช้ที่ถูกต้อง ฉันอัพเดตคำตอบแล้ว ฉันได้แก้ไขข้อบกพร่องในคำตอบเดิมของฉันซึ่งไม่อนุญาตให้สคริปต์ใช้ stdin (เพราะสคริปต์ส่งผ่านไปยัง stdin โดยไม่มีเหตุผลดี)
Gilles 'หยุดชั่วร้าย'

1

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

ทำไมไม่เพียงแค่ดาวน์โหลดสคริปต์ด้วยcurl(หรือwgetหรือsnarfหรืออะไรก็ตาม) ตรวจสอบและแก้ไขมัน (มันเป็นสคริปต์ที่หายากที่จำเป็นเคยชินบางการปรับแต่งสำหรับระบบของคุณโดยเฉพาะ) และเรียกมัน - ทั้งโดยการทำให้มันเป็นปฏิบัติการด้วยchmodหรือsh scriptname?


ฉันไม่ต้องการเครื่องมือเอนกประสงค์ ฉันจำได้ว่ามีวิธีง่าย ๆ ในการทำเช่นนี้กับเครื่องมือมาตรฐาน
Olivier Lalonde

2
การเขียนเชลล์สคริปเล็ก ๆ (อาจจะแค่ 5 เส้นหรือมากกว่านั้น) จะเป็นการยากที่จะดาวน์โหลดสคริปต์นำเสนอเพื่อดูlessหรือบางสิ่งบางอย่างแล้วถามคุณว่าคุณต้องการเรียกใช้หรือไม่ ฉันไม่เห็นว่ามันจะดีกว่าเพียงแค่ดาวน์โหลดสคริปต์ดูมันแล้วเรียกใช้ถ้ามันดูเหมือนว่าตกลง IMO มันจะแย่กว่านั้นมันจะไม่ให้ประโยชน์ใด ๆ แต่จะขจัดความยืดหยุ่นที่คุณได้รับจากการทำงานในเชลล์ของคุณ
cas

0

ใช้บรรทัดคำสั่งนี้:

curl URL | ( cat > /tmp/file; read REPLY; [[ ! $REPLY =~ ^[Yy]$ ]] && cat /tmp/file ) | sh

คุณสามารถใช้ฟังก์ชั่นเล็ก ๆ เพื่อ:

curlsh()
{
    curl "$1" \
    | ( cat > /tmp/file;read REPLY; [[ ! $REPLY =~ ^[Yy]$ ]] && cat /tmp/file ) \
    | sh
}

และกว่าใช้ด้วยวิธีนี้:

curlsh http://site.in.net/path/to/script

0

สมมติว่าคุณอ่านรู้ -p (พร้อมท์) และสคริปต์ไม่จำเป็นต้องดำเนินการกับล่ามที่กำหนดโดย shebang:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.