Panggil skrip untuk skrip lain, tetapi jangan keluar dari orang tua jika anak memanggil keluar

11

first.sh:

#! /bin/ksh
echo "prova"
. ./second.sh
echo "ho lanciato il secondo"
. ./third.sh
echo "ho lanciato il terzo"

second.sh:

echo "sono nel secondo script"
dosomething1
exit $?

Jika second.shmendeteksi kesalahan dan keluar dengan status -9, first.shselalu keluar. Bagaimana saya bisa menghindari keluar dari shell pertama jika shell anak keluar?

Saya tidak bisa mengedit second.sh.

pengguna3589887
sumber
Di sini Anda menggunakan .perintah, yang sumber file lain di shell saat ini. Tidak ada shell anak atau subkulit yang terlibat. Apakah Anda bermaksud mengeksekusi second.sh dan third.shbukannya mengambilnya?
Celada
ya .. saya harus menulis eksekusi. ./? saya ingin mengabaikan "keluar $?" di dalam second.sh .. apakah mungkin tanpa mengedit second.sh?
user3589887

Jawaban:

13

Apa yang Anda lakukan di sini termasuk second.shdan third.shsebagai sub-skrip yang berjalan dalam proses yang sama, yang disebut "sumber" dalam pemrograman shell. . ./second.shpada dasarnya setara dengan memasukkan teks second.shpada saat itu. The exitperintah keluar proses, tidak peduli apakah Anda menyebutnya dalam naskah asli atau naskah bersumber.

Jika semua yang ingin Anda lakukan adalah menjalankan perintah second.shdan third.shdan mereka tidak perlu mengakses atau memodifikasi variabel dan fungsi dari skrip asli, panggil skrip ini sebagai proses anak.

#! /bin/ksh
echo "prova"
./second.sh
echo "ho lanciato il secondo"
./third.sh
echo "ho lanciato il terzo"

Jika Anda memerlukan skrip lain untuk mengakses variabel dan fungsi dari skrip asli, tetapi tidak memodifikasinya, panggil skrip ini dalam subkulit. Subshell adalah proses yang terpisah, jadi exitkeluar hanya mereka.

#! /bin/ksh
echo "prova"
(. ./second.sh)
echo "ho lanciato il secondo"
(. ./third.sh)
echo "ho lanciato il terzo"

Jika Anda perlu menggunakan variabel atau fungsi yang didefinisikan dalam second.shdan third.shdi skrip induk, maka Anda harus terus sumbernya.

The returnbuiltin keluar hanya script bersumber dan tidak seluruh proses - itu salah satu dari beberapa perbedaan antara termasuk script lain dengan .perintah dan termasuk teks dalam naskah tua. Jika skrip bersumber hanya memanggil exitdi tingkat atas, yang bertentangan dengan fungsi di dalam, maka Anda dapat mengubahnya exitmenjadi return. Anda dapat melakukannya tanpa memodifikasi skrip dengan menggunakan alias.

#! /bin/ksh
echo "prova"
alias exit=return
. ./second.sh
echo "ho lanciato il secondo"
. ./third.sh
unalias exit
echo "ho lanciato il terzo"

Jika exitjuga disebut fungsi di dalam, saya tidak berpikir ada cara yang tidak rumit. Cara rumit adalah dengan mengatur jebakan keluar dan menempatkan kode Anda di sana.

#!/bin/ksh
do_first () {
  echo "prova"
  trap "after_second" EXIT
  . ./second.sh
  after_second
}
after_second () {
  echo "ho lanciato il secondo"
  trap "after_third" EXIT
  . ./third.sh
  after_third
}
after_third () {
  trap - EXIT
  echo "ho lanciato il terzo"
}
do_first
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Karena alasan inilah saya berhenti menggunakan '.' untuk sumber file ke dalam skrip, dan cobalah untuk secara eksklusif menggunakan 'sumber'. IMO yang harus dianggap sebagai 'praktik terbaik' bash, karena itu membuatnya lebih jelas apa yang dilakukan kode Anda.
Mark E. Hamilton
6

Alih-alih mencari shell kedua dan ketiga, jalankan saja seperti yang Anda lakukan pada perintah lain. Kode keluar dapat disimpan dan digunakan jika Anda perlu, seperti:

#! /bin/ksh
echo "prova"

# execute and capture stdout ... output of second is not seen ...
OUTPUT1=$(./second.sh)

# find out exit status of second.sh
STATUS1=$?

# ... until now
echo $OUTPUT1

# do something based on the result
if [ $STATUS1 -eq 0 ]; then 
  echo "second.sh ran successfully"
else 
  echo "second.sh crapped out"
fi

# and so on...
Dale Anderson
sumber
STATUS1=$?akan menangkap hasil dari perintah gema yang dikeluarkan sebelumnya, yang independen dari hasil ./second.sh.
Cromax
@Romax Anda benar sekali. Jawaban telah diedit.
Dale Anderson
0

Cobalah dengan cara ini (hapus dulu .saat menelepon second.sh):

first.sh:

#! /bin/ksh
echo "prova"
./second.sh
echo "ho lanciato il secondo"
./third.sh
echo "ho lanciato il terzo"

second.sh:

echo "sono nel secondo script"
dosomething1
exit $?

Ini karena .kode pendek sourceyang menyebabkan skrip kedua dimasukkan sebagai bagian dari yang pertama.

Mojtaba Rezaeian
sumber