GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana Cara Membaca Seluruh Script Shell Sebelum Mengeksekusinya?

Biasanya, jika Anda mengedit skrip, semua penggunaan skrip yang berjalan rentan terhadap kesalahan.

Sejauh yang saya mengerti, bash (cangkang lain juga?) membaca skrip secara bertahap, jadi jika Anda memodifikasi file skrip secara eksternal, itu mulai membaca hal yang salah. Apakah ada cara untuk mencegahnya?

Contoh:

sleep 20

echo test

Jika Anda menjalankan skrip ini, bash akan membaca baris pertama (katakanlah 10 byte) dan tidur. Saat dilanjutkan, mungkin ada konten yang berbeda dalam skrip mulai dari byte ke-10. Saya mungkin berada di tengah-tengah baris dalam skrip baru. Dengan demikian skrip yang berjalan akan rusak.

Jawaban yang Diterima:

Ya shell, dan bash khususnya, berhati-hatilah untuk membaca file satu baris dalam satu waktu, sehingga cara kerjanya sama seperti saat Anda menggunakannya secara interaktif.

Anda akan melihat bahwa ketika file tidak dapat dicari (seperti pipa), bash bahkan membaca satu byte pada satu waktu untuk memastikan tidak membaca melewati \n karakter. Saat file dapat dicari, file akan dioptimalkan dengan membaca blok penuh sekaligus, tetapi mencari kembali setelah \n .

Artinya, Anda dapat melakukan hal-hal seperti:

bash << \EOF
read var
var's content
echo "$var"
EOF

Atau tulis skrip yang memperbarui diri. Yang tidak akan dapat Anda lakukan jika tidak memberikan jaminan itu.

Sekarang, Anda jarang ingin melakukan hal seperti itu dan, seperti yang Anda ketahui, fitur itu cenderung lebih sering mengganggu daripada berguna.

Untuk menghindarinya, Anda dapat mencoba dan memastikan Anda tidak mengubah file di tempat (misalnya, mengubah salinan, dan memindahkan salinan di tempatnya (seperti sed -i atau perl -pi dan beberapa editor melakukannya misalnya)).

Atau Anda bisa menulis skrip Anda seperti:

{
  sleep 20
  echo test
}; exit

(perhatikan bahwa penting bahwa exit berada di baris yang sama dengan }; meskipun Anda juga bisa memasukkannya ke dalam kurung kurawal tepat sebelum kurung kurawal penutup).

atau:

main() {
  sleep 20
  echo test
}
main "[email protected]"; exit

Shell perlu membaca skrip hingga exit sebelum mulai melakukan apapun. Itu memastikan shell tidak akan membaca dari skrip lagi.

Itu berarti seluruh skrip akan disimpan dalam memori.

Itu juga dapat memengaruhi penguraian skrip.

Misalnya, di bash :

export LC_ALL=fr_FR.UTF-8
echo $'St\ue9phane'

Akan menampilkan U+00E9 yang dikodekan dalam UTF-8. Namun, jika Anda mengubahnya menjadi:

{
  export LC_ALL=fr_FR.UTF-8
  echo $'St\ue9phane'
}

\ue9 akan diperluas dalam rangkaian karakter yang berlaku pada saat perintah itu diuraikan yang dalam hal ini adalah sebelum export perintah dijalankan.

Terkait:SSH – skrip untuk mengotomatiskan scp di jaringan?

Perhatikan juga bahwa jika source alias . perintah digunakan, dengan beberapa shell, Anda akan memiliki masalah yang sama untuk file sumber.

Itu bukan kasus bash meskipun yang source perintah membaca file sepenuhnya sebelum menafsirkannya. Jika menulis untuk bash secara khusus, Anda sebenarnya dapat memanfaatkannya, dengan menambahkan di awal skrip:

if [[ ! $already_sourced ]]; then
  already_sourced=1
  source "$0"; exit
fi

(Saya tidak akan bergantung pada itu karena Anda dapat membayangkan versi bash di masa mendatang dapat mengubah perilaku yang saat ini dapat dilihat sebagai batasan (bash dan AT&T ksh adalah satu-satunya shell seperti POSIX yang berperilaku seperti itu sejauh yang dapat diketahui) dan already_sourced triknya agak rapuh karena mengasumsikan bahwa variabel tidak ada di lingkungan, belum lagi itu mempengaruhi konten variabel BASH_SOURCE)


Linux
  1. Menyesuaikan shell Bash

  2. Bagaimana BASH Shell memuat file konfigurasinya di Linux

  3. Bagaimana saya tahu nama file skrip dalam skrip Bash?

  1. Cara membaca hanya satu karakter dalam skrip shell

  2. Cara memasukkan file dalam skrip bash shell

  3. Apa perbedaan antara menjalankan skrip Bash vs sumbernya?

  1. Cara Menggunakan Kata Sandi Terenkripsi di Linux Bash Shell Script

  2. Bagaimana Cara Mendapatkan Alamat Ip Eksternal Dalam Script Shell?

  3. Bagaimana Cara Men-debug Skrip Bash?