Dapatkah Anda mengedit skrip shell saat sedang berjalan dan apakah perubahannya memengaruhi skrip yang sedang berjalan?
Saya ingin tahu tentang kasus spesifik dari skrip csh yang saya miliki batch menjalankan banyak rasa build yang berbeda dan berjalan sepanjang malam. Jika sesuatu terjadi pada saya di tengah operasi, saya ingin masuk dan menambahkan perintah tambahan, atau mengomentari perintah yang tidak dijalankan.
Jika tidak memungkinkan, apakah ada shell atau mekanisme batch yang memungkinkan saya melakukan ini?
Tentu saja saya sudah mencobanya, tetapi akan memakan waktu berjam-jam sebelum saya melihat apakah itu berhasil atau tidak, dan saya ingin tahu tentang apa yang terjadi atau tidak terjadi di balik layar.
Jawaban:
Skrip tidak berfungsi seperti itu; salinan yang dijalankan tidak bergantung pada file sumber yang Anda edit. Lain kali skrip dijalankan, ini akan didasarkan pada versi file sumber yang terakhir disimpan.
Mungkin bijaksana untuk memecah skrip ini menjadi beberapa file, dan menjalankannya satu per satu. Ini akan mengurangi waktu eksekusi hingga gagal. (yaitu, bagi batch menjadi satu skrip ragam build, jalankan masing-masing skrip satu per satu untuk melihat mana yang menyebabkan masalah).
sumber
Itu memang memengaruhi, setidaknya pesta di lingkungan saya, tetapi dengan cara yang sangat tidak menyenangkan . Lihat kode-kode ini. Pertama
a.sh
:#!/bin/sh echo "First echo" read y echo "$y" echo "That's all."
b.sh
:#!/bin/sh echo "First echo" read y echo "Inserted" echo "$y" # echo "That's all."
Melakukan
$ cp a.sh run.sh $ ./run.sh $ # open another terminal $ cp b.sh run.sh # while 'read' is in effect $ # Then type "hello."
Dalam kasus saya, hasilnya selalu:
(Tentu saja jauh lebih baik untuk mengotomatiskannya, tetapi contoh di atas dapat dibaca.)
[Sunting] Ini tidak dapat diprediksi, dengan demikian berbahaya. Solusi terbaik adalah , seperti yang dijelaskan di sini, masukkan semua ke dalam penjepit, dan sebelum penjepit penutup, masukkan "keluar" . Baca jawaban terkait dengan baik untuk menghindari jebakan.
[ditambahkan] Perilaku sebenarnya bergantung pada satu baris baru tambahan, dan mungkin juga pada rasa Unix Anda, sistem file, dll. Jika Anda hanya ingin melihat beberapa pengaruh, cukup tambahkan "echo foo / bar" ke b.sh sebelum dan / atau sesudahnya baris "baca".
sumber
b.sh
dengan menambahkan 10 baris echo foo / bar / baz. Inti dari jawaban oleh dave4220 dan saya adalah bahwa efeknya tidak mudah diprediksi. (BTW kata benda "kasih sayang" berarti "cinta" =)Coba ini ... buat file bernama
bash-is-odd.sh
:#!/bin/bash echo "echo yes i do odd things" >> bash-is-odd.sh
Itu menunjukkan bahwa bash memang menafsirkan skrip "saat Anda pergi". Memang, mengedit skrip yang berjalan lama memiliki hasil yang tidak dapat diprediksi, memasukkan karakter acak, dll. Mengapa? Karena bash membaca dari posisi byte terakhir, jadi pengeditan menggeser lokasi karakter saat ini yang sedang dibaca.
Singkatnya, Bash sangat, sangat tidak aman karena "fitur" ini. svn dan
rsync
ketika digunakan dengan skrip bash sangat mengganggu, karena secara default mereka "menggabungkan" hasil ... pengeditan di tempat.rsync
memiliki mode yang memperbaikinya. svn dan git tidak.Saya menyajikan solusi. Buat file bernama
/bin/bashx
:#!/bin/bash source "$1"
Sekarang gunakan
#!/bin/bashx
pada skrip Anda dan selalu jalankan denganbashx
bukanbash
. Ini memperbaiki masalah - Anda dapat dengan amanrsync
membuat skrip Anda.Solusi alternatif (in-line) yang diusulkan / diuji oleh @ AF7:
{ # your script } exit $?
Kawat gigi keriting melindungi dari pengeditan, dan perlindungan keluar dari penambahan. Tentu saja, kita semua akan jauh lebih baik jika bash hadir dengan opsi, seperti
-w
(seluruh file), atau sesuatu yang melakukan ini.sumber
Pisahkan skrip Anda menjadi beberapa fungsi, dan setiap kali suatu fungsi memanggil Anda
source
dari file terpisah. Kemudian Anda dapat mengedit file kapan saja dan skrip Anda yang sedang berjalan akan mengambil perubahan saat bersumber lagi.foo() { source foo.sh } foo
sumber
Pertanyaan bagus! Semoga skrip sederhana ini membantu
#!/bin/sh echo "Waiting..." echo "echo \"Success! Edits to a .sh while it executes do affect the executing script! I added this line to myself during execution\" " >> ${0} sleep 5 echo "When I was run, this was the last line"
Tampaknya di bawah linux bahwa perubahan yang dilakukan pada eksekusi .sh diberlakukan oleh skrip pelaksana, jika Anda dapat mengetik cukup cepat!
sumber
Catatan tambahan yang menarik - jika Anda menjalankan skrip Python itu tidak berubah. (Ini mungkin sangat jelas bagi siapa pun yang memahami bagaimana shell menjalankan skrip Python, tetapi berpikir ini mungkin pengingat yang berguna bagi seseorang yang mencari fungsi ini.)
Saya menciptakan:
#!/usr/bin/env python3 import time print('Starts') time.sleep(10) print('Finishes unchanged')
Kemudian di shell lain, saat ini sedang tidur, edit baris terakhir. Saat ini selesai, ini akan menampilkan garis tidak berubah, mungkin karena menjalankan
.pyc
? Hal yang sama terjadi di Ubuntu dan macOS.sumber
Saya belum menginstal csh, tapi
#!/bin/sh echo Waiting... sleep 60 echo Change didn't happen
Jalankan itu, edit baris terakhir dengan cepat untuk dibaca
echo Change happened
Outputnya adalah
Waiting... /home/dave/tmp/change.sh: 4: Syntax error: Unterminated quoted string
Hrmph.
Saya kira pengeditan pada skrip shell tidak akan berpengaruh sampai mereka dijalankan ulang.
sumber
Change didn'ned
.Jika ini semua dalam satu skrip, maka tidak itu tidak akan berhasil. Namun, jika Anda mengaturnya sebagai skrip driver yang memanggil sub-skrip, maka Anda mungkin dapat mengubah sub-skrip sebelum dipanggil, atau sebelum dipanggil lagi jika Anda melakukan perulangan, dan dalam hal ini saya percaya perubahan itu akan tercermin dalam eksekusi.
sumber
Saya tidak mendengar ... tapi bagaimana dengan beberapa tipuan:
BatchRunner.sh
Command1.sh Command2.sh
Command1.sh
Command2.sh
Maka Anda harus dapat mengedit konten setiap file perintah sebelum BatchRunner melakukannya, bukan?
ATAU
Versi yang lebih bersih akan membuat BatchRunner melihat ke satu file di mana ia akan menjalankan satu baris secara berurutan. Maka Anda harus bisa mengedit file kedua ini saat file pertama berjalan, bukan?
sumber
Gunakan Zsh sebagai gantinya untuk skrip Anda.
AFAICT, Zsh tidak menunjukkan perilaku yang membuat frustrasi ini.
sumber
biasanya, tidak biasa mengedit skrip Anda saat sedang berjalan. Yang harus Anda lakukan adalah melakukan pemeriksaan kendali atas operasi Anda. Gunakan pernyataan if / else untuk memeriksa kondisi. Jika ada yang gagal, lakukan ini, kalau tidak lakukan itu. Itulah cara untuk pergi.
sumber