GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana Cara Menangkap Status Pengembalian Dan Menggunakan Tee Pada Saat Yang Sama Di Korn Shell??

Pertanyaan ini sudah memiliki jawaban di sini :Dapatkan status keluar dari proses yang disalurkan ke yang lain

(16 jawaban)
Tutup 7 tahun yang lalu.

Pertimbangkan Kode sumber:

1. Parent.sh

#!/usr/bin/ksh
# No tee
ksh Child.sh;
exit_status=$?;
echo "Exit status: ${exit_status}"
# Using tee
ksh Child.sh | tee -a log.txt;
exit_status=$?;
echo "Exit status: ${exit_status}"

2. Child.sh

#!/usr/bin/ksh
...
exit 1;

Keluaran:

Exit status: 1
Exit status: 0
  • Variabel $exit_status menangkap status keluar Child.sh dan begitu juga 1 .
  • Dalam kasus kedua, $exit_status sedang menangkap status keluar dari tee, yaitu .

Jadi bagaimana cara menangkap status keluar dan juga menggunakan tee?

Jawaban yang Diterima:

Direproduksi (dan ditingkatkan) dari FAQ comp.unix.shell (karena saya kebetulan telah menulis bagian FAQ itu):

Bagaimana cara mendapatkan kode keluar cmd1 di cmd1|cmd2

Pertama, perhatikan bahwa kode keluar cmd1 mungkin bukan nol dan tetap tidak
berarti kesalahan. Ini terjadi misalnya di

cmd | head -n 1

anda mungkin mengamati status keluar 141 (atau 269 dengan ksh93, atau 397 dengan yash) dari cmd ,
tapi itu karena cmd diinterupsi oleh sinyal SIGPIPE saat head -n 1 dihentikan setelah membaca satu baris.

Untuk mengetahui status keluar dari elemen pipa

cmd1 | cmd2 | cmd3

dengan zsh (dan ikan 3.1+):

Kode keluar disediakan di pipestatus susunan khusus. cmd1 kode keluar ada di $pipestatus[1] , cmd3 keluar kode di $pipestatus[3] , sehingga $status /$? selalu sama dengan $pipestatus[-1] .

dengan bash:

Kode keluar disediakan di PIPESTATUS susunan khusus. cmd1 kode keluar ada di ${PIPESTATUS[0]} , cmd3 kode keluar di ${PIPESTATUS[2]} , sehingga $? selalu sama dengan ${PIPESTATUS[-1]} (atau ${PIPESTATUS[@]: -1} untuk versi yang lebih lama dari 4.2).

dengan cangkang seperti Bourne lainnya

Anda perlu menggunakan trik untuk meneruskan kode keluar ke shell utama. Anda dapat melakukannya
menggunakan pipa(2). Alih-alih menjalankan cmd1 , Anda menjalankan cmd1; echo "$?" dan membuat
yakin $? menuju ke cangkangnya.

exec 3>&1
code=`
  # now, inside the backticks, fd4 goes to the pipe
  # whose other end is read and stored in $code  for
  # later evaluation; fd1 is the normal standard output
  # preserved the line before with exec 3>&1

  exec 4>&1 >&3 3>&- 
  {
    cmd1 4>&-; echo "ec1=$?;" >&4
  } | {
    cmd2 4>&-; echo "ec2=$?;" >&4
  } | cmd3 4>&-
  echo "ec3=$?;" >&4
`
exec 3>&-
eval "$code"

Keluar dari kode di $ec1 , $ec2 , $ec3 .

dengan cangkang POSIX

Anda dapat menggunakan fungsi ini untuk mempermudah:

run() {
  j=1
  while eval "${pipestatus_$j+:} false"; do
    unset "pipestatus_$j"
    j=$(($j+1))
  done
  j=1 com= k=1 l=
  for arg do
    case $arg in
      ('|')
        com="$com {
               $l "'3>&-
               echo "pipestatus_'$j'=$?" >&3
             } 4>&- |'
        j=$(($j+1)) l=;;
      (*)
        l="$l "${$k}""
    esac
    k=$(($k+1))
  done
  com="$com $l"' 3>&- >&4 4>&-
       echo "pipestatus_'$j'=$?"'

  { eval "$(exec 3>&1; eval "$com")"; } 4>&1
  j=1
  ret=0
  while eval "${pipestatus_$j+:} false"; do
    eval '[ "$pipestatus_'"$j"'" -eq 0 ] || ret=$pipestatus_'"$j"
    j=$(($j+1))
  done
  return "$ret"
}

Gunakan sebagai:

run cmd1 | cmd2 | cmd3

kode keluar ada di $pipestatus_1 , $pipestatus_2 , $pipestatus_3 dan $? adalah status keluar bukan nol paling kanan (seperti dengan pipefail pilihan beberapa shell).

Terkait:Memulihkan file yang terhapus secara tidak sengaja?
Linux
  1. Cara Membuat Alias ​​​​dan Menggunakan Perintah Alias ​​​​di Linux

  2. Salin dan chmod/chown secara bersamaan

  3. Ping dan tcpdump secara bersamaan

  1. Cara Menggunakan Perintah Sentuh Linux + Contoh

  2. Cara Menyalin File Dan Mengubah Kepemilikan, Izin Pada Saat Yang Sama

  3. Cara Menginstal dan Menggunakan Perintah Ping di Linux

  1. Bagaimana Menyalin File Dan Membuat Direktori Target Pada Saat Yang Sama?

  2. Bash + Bagaimana Cara Keluar Dari Skrip Sekunder Dan Dari Skrip Utama Pada Kedua Kalinya?

  3. Cara mendapatkan status keluar satu lingkaran di bash