GNU/Linux >> Belajar Linux >  >> Linux

Dalam `sementara Ifs=Read..`, Mengapa Ifs Tidak Berpengaruh?

Saya mungkin memiliki sesuatu yang benar-benar salah, tetapi tampaknya meyakinkan bagi saya, bahwa menyetel IFS sebagai salah satu perintah dalam daftar pra-kerja/selesai sama sekali tidak berpengaruh.
IFS luar (di luar while konstruksi) berlaku di semua contoh yang ditunjukkan dalam skrip di bawah ini..

Apa yang terjadi di sini? Apakah saya salah paham tentang apa yang dilakukan IFS dalam situasi ini? Saya mengharapkan hasil pemisahan array seperti yang ditunjukkan pada kolom "yang diharapkan".

#!/bin/bash
xifs() { echo -n "$(echo -n "$IFS" | xxd -p)"; } # allow for null $IFS 
show() { x=($1) 
         echo -ne "  (${#x[@]})t |"
         for ((j=0;j<${#x[@]};j++)); do 
           echo -n "${x[j]}|"
         done
         echo -ne "t"
         xifs "$IFS"; echo
}
data="a  b   c"
echo -e "-----   --  -- t --------tactual"
echo -e "outside        t  IFS    tinside" 
echo -e "loop           t Field   tloop" 
echo -e "IFS     NR  NF t Split   tIFS (actual)" 
echo -e "-----   --  -- t --------t-----"
IFS=$' tn'; xifs "$IFS"; echo "$data" | while         read; do echo -ne 't 1'; show "$REPLY"; done 
IFS=$' tn'; xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne 't 2'; show "$REPLY"; done 
IFS=$' tn'; xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne 't 3'; show "$REPLY"; done
IFS=" ";      xifs "$IFS"; echo "$data" | while         read; do echo -ne 't 4'; show "$REPLY"; done 
IFS=" ";      xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne 't 5'; show "$REPLY"; done 
IFS=" ";      xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne 't 6'; show "$REPLY"; done
IFS=;         xifs "$IFS"; echo "$data" | while         read; do echo -ne 't 7'; show "$REPLY"; done 
IFS=;         xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne 't 8'; show "$REPLY"; done 
IFS=;         xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne 't 9'; show "$REPLY"; done
IFS=b;        xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne 't10'; show "$REPLY"; done
IFS=b;        xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne 't11'; show "$REPLY"; done
echo -e "-----   --  -- t --------t-----"

Keluaran:

-----   --  --   --------       actual   
outside           IFS           inside                assigned   
loop             Field          loop    #              inner
IFS     NR  NF   Split          IFS     #  expected    IFS
-----   --  --   --------       -----   #  ---------  --------
20090a   1  (3)  |a|b|c|        20090a  #                              
20090a   2  (3)  |a|b|c|        20090a  #  |a  b   c|  IFS=
20090a   3  (3)  |a|b|c|        20090a  #  |a  |   c|  IFS=b
20       4  (3)  |a|b|c|        20      #                          
20       5  (3)  |a|b|c|        20      #  |a  b   c   IFS=
20       6  (3)  |a|b|c|        20      #  |a  |   c|  IFS=b
         7  (1)  |a  b   c|             #                          
         8  (1)  |a  b   c|             #  |a|b|c|     IFS=" "
         9  (1)  |a  b   c|             #  |a  |   c|  IFS=b
62      10  (2)  |a  |   c|     62      #  |a  b   c|  IFS=
62      11  (2)  |a  |   c|     62      #  |a|b|c|     IFS=" "
-----   --  --   --------       -----      ---------   -------                        

Jawaban yang Diterima:

(Maaf, penjelasannya panjang)

Ya, IFS variabel di while IFS=" " read; do … tidak berpengaruh pada sisa kode.

Terkait:Baca informasi di dalam PDF?

Mari kita perjelas dulu bahwa baris perintah shell menampilkan dua jenis variabel yang berbeda:

  • variabel shell (yang hanya ada di dalam shell, dan lokal untuk shell)
  • variabel lingkungan, yang ada untuk setiap proses. Itu biasanya disimpan pada fork() dan exec() , jadi proses anak mewarisinya.

Saat Anda memanggil perintah dengan:

  A=foo B=bar command

perintah dijalankan di dalam lingkungan di mana (lingkungan) variabel A diatur ke foo dan B diatur ke bar . Tetapi dengan baris perintah ini, variabel shell saat ini A dan B dibiarkan tidak berubah .

Ini berbeda dengan:

A=foo; B=bar; command

Di sini, variabel shell A dan B didefinisikan dan perintah dijalankan tanpa variabel lingkungan A dan B didefinisikan. Nilai A dan B tidak dapat diakses dari command .

Namun, jika beberapa variabel shell adalah export -ed, variabel lingkungan yang sesuai disinkronkan dengan variabel shell masing-masing. Contoh:

export A
export B
A=foo; B=bar; command

Dengan kode ini, keduanya shell variabel dan shell lingkungan variabel diatur ke foo dan bar . Karena variabel lingkungan diwarisi oleh sub-proses, command akan dapat mengakses nilainya.

Untuk kembali ke pertanyaan awal Anda, di:

IFS='a' read

hanya read terpengaruh. Dan sebenarnya, dalam hal ini, read tidak peduli dengan nilai IFS variabel. Ini menggunakan IFS hanya ketika Anda meminta baris untuk dipisahkan (dan disimpan dalam beberapa variabel), seperti di:

echo "a :  b :    c" | IFS=":" read i j k; 
    printf "i is '%s', j is '%s', k is '%s'" "$i" "$j" "$k"

IFS tidak digunakan oleh read kecuali jika dipanggil dengan argumen. (Sunting: Ini tidak sepenuhnya benar:karakter spasi putih, yaitu spasi dan tab, ada di IFS selalu diabaikan di awal/akhir baris input. )


Linux
  1. Mengapa `md5sum` Tidak Memberikan Hash yang Sama Seperti Internet?

  2. Linux – Ionice Tidak Memiliki Efek Pada Penulisan yang Tidak Disinkronkan (yaitu Penulisan Normal)?

  3. Mengapa `keluar &` Tidak Berfungsi?

  1. Mengapa '/' Memiliki Entri '..'?

  2. Apakah Python memiliki sinkronisasi?

  3. Saat mengatur IFS untuk dibagi pada baris baru, mengapa perlu menyertakan backspace?

  1. Apa itu GPU Matrox dan mengapa server UNIX universitas saya memilikinya?

  2. Mengapa sistem saya hanya menampilkan RAM 3,2 GiB padahal saya pasti memiliki 4,0 GiB

  3. Apa yang dimaksud dengan gema $? melakukan?