Apakah `jika` dan` maka` sebenarnya program

15

Saya pernah membaca bahwa titik koma digunakan untuk memisahkan program:

$ echo 3; ls -la

Apakah ini berarti if, thendan elseapakah ada program terpisah di sini?

$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi

Pertanyaan ini bukan tentang titik koma.

Maxim Koretskyi
sumber
2
Kemungkinan duplikat titik koma dalam struktur bersyarat
Stephen Rauch
1
@StephenRauch Bukan duplikat. Lebih lanjut, ini merupakan hasil wajar dari Q itu, sebagai upaya untuk memahami lebih jauh.
user207673
Formulasi program-y lainnya:[ $variable == abcdef ] && echo yes || echo no
Hagen von Eitzen
2
@HagenvonEitzen yang tidak sepenuhnya setara, jika pernyataan dalam cabang pertama gagal, yang kedua juga akan dieksekusi.
Morgen
Kemungkinan duplikat dari apa saja operator kontrol dan pengalihan shell?
G-Man Mengatakan 'Reinstate Monica'

Jawaban:

26

The ;memisahkan pernyataan (longgar berbicara). Itu (hampir) selalu mungkin untuk mengganti ;dengan baris baru.

Untuk mengatakan bahwa ;memisahkan dua program, oleh karena itu ifdan thenharus "program" agak terlalu sederhana karena pernyataan dapat dibuat dari kata-kata yang dicadangkan, fungsi shell, utilitas bawaan dan utilitas eksternal, dan kombinasi dari ini menggunakan pipa dan operator boolean dll dll.

Keduanya ifdan thendilindungi kata-kata dalam tata bahasa shell , bukan "program". Di sini mereka digunakan untuk membangun apa yang secara teknis disebut perintah gabungan .

echokemungkinan merupakan utilitas bawaan di shell (tetapi tidak harus), dan lsmungkin merupakan utilitas eksternal (atau "program" seperti yang Anda katakan).

Kusalananda
sumber
7

Sementara itu adalah perkiraan pertama yang adil ketika seseorang mulai mempelajari dasar-dasar penggunaan shell, pada level "di sini adalah bagaimana seseorang menjalankan program" dan "di sini adalah bagaimana seseorang menjalankan banyak program satu demi satu pada satu baris" , itu sebenarnya tidak benar.

Semakin sulit dipahami oleh pemula tetapi penjelasan yang lebih tepat adalah bahwa bahasa shell adalah bahasa komputer . Ini memiliki sintaks . Sintaks itu terdiri dari berbagai elemen leksikal termasuk (antara lain) baris baru, operator, kata-kata, dan kata-kata yang dicadangkan.

if, then, else, Dan fisemua kata-kata reserved . Mereka memiliki makna khusus ketika mengurai input yang diberikan seseorang ke shell, sesuai dengan tata bahasanya . Begitu pula ;dengan operator pemisah .

Input dalam bahasa shell dengan demikian, diambil secara keseluruhan, program komputer yang ditafsirkan oleh program lain, seorang juru bahasa , shell. Bagian gramatikal individualnya bukan program. Bahasa shell adalah cara untuk menentukan program (lainnya) untuk dijalankan oleh shell.

[bukan elemen leksikal khusus dalam tata bahasa shell seperti operator. Ini adalah kata yang biasa , yang menamai satu nama program tersebut [. Banyak shell memiliki versi built-in dari program ini, digabungkan ke dalam kode program shell itu sendiri, tetapi Anda juga dapat menemukan program eksternal dengan nama ini di suatu tempat seperti /bin/[atau /usr/bin/[, yang mana program selain shell dapat meminta. Sama, ]bukan elemen leksikal shell khusus baik. Itu kata biasa, yang menjadi argumen untuk [program ini. The [Program mensyaratkan bahwa argumen akhir, ketika dijalankan, menjadi ], yang hasil untuk kemudian mengabaikan.

Program serupa lainnya yang disebutkan dalam pertanyaan Anda adalah echo. Sekali lagi, sebagian besar shell memiliki versi bawaan dari program ini. Tetapi sekali lagi ada juga versi eksternal dari program, di suatu tempat seperti /bin/echoatau /usr/bin/echo, untuk program selain memohon kerang.

Program ketiga yang disebutkan dalam pertanyaan Anda adalah ls. Shell umumnya tidak memiliki versi built-in dari program ini, dan ini adalah program eksternal, dapat ditemukan di suatu tempat seperti /bin/lsatau /usr/bin/ls.

Untuk shell Bourne Again, Anda dapat membaca lebih lanjut tentang ini di Fitur Shell Dasar dari GNU Bourne Again dokumentasi info shell. Kerang lain memiliki tata bahasa yang berbeda, secara alami. The Spesifikasi Single Unix menggambarkan sintaks bahwa semua kerang POSIX-konforman (dalam mode POSIX-konforman mereka) seharusnya mematuhi untuk.

Bacaan lebih lanjut

  • " Shell Grammar ". Bahasa Perintah Shell . Spesifikasi Spesifikasi Dasar 7. Grup Terbuka. IEEE 1003.1-2008. ISBN 1937218812.
  • test. Utilitas . Spesifikasi Spesifikasi Dasar 7. Grup Terbuka. IEEE 1003.1-2008. ISBN 1937218812.
  • " Shell Grammar ". Manual Z Shell . versi 5.3.1. 2017
JdeBP
sumber
5

Ini sebenarnya tidak dibuat-buat untuk dipikirkan if, thendan elsesebagai program eksternal. Bahkan, shell Thompson di Unix edisi 1 asli diimplementasikan ifdan gotosebagai program eksternal. Hal ini dimungkinkan karena subproses membagikan deskriptor file dengan proses shell, jadi goto (forward) hanya harus membaca input sampai menemukan label target dan kemudian keluar. Lihat cangkang Thompson .

Johan Myréen
sumber
Atau memang melihat Laurent Bercot's ifdan ifelse, yang merupakan bagian dari execline. Ini bukan ifpertanyaannya.
JdeBP
2
"Sebenarnya tidak terlalu mengada-ada untuk menganggap jika, dulu dan lagi sebagai program eksternal" Ya, memang, karena tidak.
Lightness Races dengan Monica
2

Itu thendan elsebukan program. Bagian lainnya adalah. Perhatikan tidak ada ;'langsung setelah mereka, tetapi setelah perintah mereka mendahului.

Ini [ ... ] adalah perintah, dan perlu ;jika diikuti dengan awal dari perintah lain.

AFAIK, semua struktur kontrol di Bash, dan mungkin kebanyakan shell * nix, adalah sama. Mereka adalah instruksi untuk penerjemah. Tes atau kondisi, di sisi lain, menggunakan program / proses yang "dieksekusi" dan merupakan perintah. Karena thenmerupakan bagian dari baris yang mengarah ke echoperintah itu harus dipisahkan oleh baris baru dari perintah sebelumnya [ ... ]. Tidak perlu dipisahkan dari perintah yang dikontrolnya, the echo yes.

Secara hukum, meski jelek dan sulit dibaca, Anda juga bisa melakukan ini.

if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi

Perhatikan bahwa tidak perlu untuk ;antara kontrol sama sekali di sini, meskipun mereka tidak di jalur mereka sendiri.

Cukup menarik, seluruh struktur kontrol ( if ... fi) adalah perintah shell, dan keseluruhannya harus diakhiri dengan baris baru atau a ;. Baris terakhir tidak bisa fi echo donetetapi harus fi; echo done. Sama seperti tugas VARIABLE='abcdef'adalah perintah.

Meskipun seluruh struktur kontrol adalah perintah, mereka masih bukan program.

pengguna207673
sumber
1

if, elif, then, Dan fisemua kata kunci dicadangkan digunakan untuk mengimplementasikan salah satu konstruksi disebut sebagai perintah senyawa di shell, yang berarti tidak mungkin ada perintah (atau lebih tepatnya, perintah lain) oleh salah satu dari mereka nama-nama di shell. Tujuan dari ;umumnya bukan untuk memisahkan perintah, tetapi untuk mengakhiri daftar perintah . Misalnya, berikut ini adalah ifpernyataan yang valid :

if echo foo; echo bar; echo baz; then echo done; echo really done; fi

Kondisi ifpernyataan adalah daftar perintah echo foo; echo bar; echo baz. Parser tahu bahwa kondisinya sudah berakhir karena then, yang segera mengikuti tanda titik koma, tidak dapat menjadi perintah karena itu adalah kata kunci yang dipesan. Dengan demikian, ia tahu bahwa yang mengikuti then adalah awal dari tubuh. Demikian juga, fiadalah kata kunci yang dipesan dan dengan demikian tidak bisa menjadi perintah ketiga di tubuh ifpernyataan, tetapi menandai akhir dari perintah majemuk.

chepner
sumber
terima kasih, jika ini digunakan if program1 foo; program2 bar; program3 baz; , status program mana yang seharusnya 0, sehingga shell dilanjutkan then? Yang terakhir?
Maxim Koretskyi
Adil program3 baz. Status keluar dari daftar perintah adalah status keluar dari perintah terakhir dalam daftar itu. Dua lainnya bisa gagal tanpa mempengaruhi kondisinya.
chepner