Curl'den sh'ye borulamadan önce kabuk betiğini okuyun ve onaylayın (curl -s [url] | sh)


11

Web'den bir kabuk komut dosyası yürütmem gerektiğinde, komut dosyasının kötü amaçlı olmadığından ve çalıştırılmasının güvenli olduğundan emin olmak için curl -s [url] | shönce urlweb tarayıcımda açarım .

Komut dosyasını komut satırından okumak ve sonra komut dosyasını okuduktan sonra yürütmeyi onaylamak mümkün kılan bir komut satırı hile gördüğümü hatırlıyorum. Doğru hatırlıyorsam, benzer bir şeye benziyordu curl -s [url] | something...here | shve herhangi bir yazılım yüklemesi gerektirmiyordu.

Bu numarayı bilen var mı?

Yanıtlar:


5

Bir yardımcı program vardır moreutilsdenir vipeşovlarının revew ve Stdout'a geçti alır önce dosyayı değiştirebilir editör, içinde stdin'i söyledi.

Yüklemek istemiyorsanız moreutils, aşağıdakine benzer bir şey başarabilirsiniz:

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

mktempiçinde coreutilsve büyük olasılıkla sisteminizde zaten yüklü.


2

Açıkladığınız şeyi yapacak tek bir yardımcı program düşünemiyorum, ancak bunu bir kabuk snippet'i yapmak için yeterince kolay.

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

Bu, komut dosyasının bir metin dosyası olduğunu varsayar. Boş baytlar desteklenmez: kabuğa bağlı olarak kaldırılabilir veya bir satırın veya tüm dosyanın kısaltılmasına neden olabilir. Ayrıca dosyanın sonundaki tüm yeni satırlar kaldırılır (heredoc yapısı bir geri ekler). Bu normalde bir komut dosyası için bir sorun değildir, ancak örneğin komut dosyasının ayıkladığı ikili biçimde bir arşivle bitmesi olabilir. Bu, bir dosyayı dağıtmanın çok güvenilir bir yolu değildir, çünkü böyle bir ikili komut dosyasının bir noktada yanlış kodlanması riski vardır. Bununla birlikte, komut dosyasını geçici bir dosyaya yazarak işleyebilirsiniz.

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"

$()ilk satırda alıntılanmalıdır. Ayrıca, girişteki NUL karakterlerini kaldırabilir ve bu da ölümcül olabilir (örneğin, kendi kendine ayıklanan bir komut dosyasında).
l0b0

1
@ l0b0 Bir ödevde alıntı yapmanız gerekmiyor, ancak tartışmasız iyi bir stil . Boş satırlar da son satırsonları gibi kaybolur; kabuk betiğine bir arşiv ekleyecekseniz, base64 gibi bir metin kodlaması kullanmanızı öneririm.
Gilles 'SO- kötü olmayı bırak'

Her zamanki gibi tüm geçerli noktalar. +1
l0b0

@ l0b0 İkinci düşüncelerde, biraz risk altında olsa da, bu geçerli bir kullanım durumudur. Cevabımı güncelledim. Ayrıca orijinal cevabımdaki betiğin stdin'i kullanmasına izin vermeyen bir kusuru düzelttim (çünkü senaryo stdin'e geçti, çünkü iyi bir sebep yok).
Gilles 'SO- kötü olmayı bırak'

1

Özel bir araca ihtiyaç duyacak kadar sık ​​sık indirmek ve çalıştırmak için bir komut dosyası (veya kaynak) bulacağınız yerde neden bunu yapmak istediğinizi hayal etmek zordur.

Neden sadece betiği curl(ya da wgetya snarfda her neyse) indirmiyor, inceleyip düzenleyemiyorsunuz (özel sisteminiz için bazı özelleştirme gerektirmeyecek nadir bir betik) ve sonra çalıştırılabilir - ya chmodda ile çalıştırılabilir hale getirerek sh scriptname?


Özel amaçlı bir araç istemiyorum. Bunu standart araçlarla yapmanın kolay bir yolu olduğunu hatırlıyorum.
Olivier Lalonde

2
Bir komut dosyasını indirmek, görüntülemek lessveya sunmak için sunmak için küçük bir kabuk komut dosyası (muhtemelen sadece 5 veya daha fazla satır) yazmak zor olmaz ve ardından çalıştırmak isteyip istemediğinizi sorar. Ben sadece komut dosyası indirmek, görüntüleme ve sonra Tamam görünüyorsa çalışan daha iyi olacağını göremiyorum. IMO daha kötü olurdu, herhangi bir avantaj sunmaz, ancak sadece kabuğunuzda çalışmaktan elde ettiğiniz esnekliği ortadan kaldırır.
cas

0

Bu komut satırını kullanın:

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

Bunun için küçük bir işlev kullanabilirsiniz:

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

Ve bu şekilde kullanmaktan:

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

0

Senin varsayarsak okuma -p (istemi) bilir ve senaryo ihtiyacı shebang tarafından belirtilen tercüman ile yürütülmez:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.