Beranda » bagaimana » Panduan Pemula untuk Shell Scripting 2 For Loops

    Panduan Pemula untuk Shell Scripting 2 For Loops

    Jika Anda ingin membangun kredibilitas geek Anda, bergabunglah dengan kami untuk angsuran kedua dalam seri skrip shell kami. Kami memiliki beberapa koreksi, beberapa perbaikan pada skrip minggu lalu, dan panduan tentang pengulangan untuk yang belum tahu.

    Script datecp direvisi

    Dalam angsuran pertama panduan skrip shell kami, kami membuat skrip yang menyalin file ke direktori cadangan setelah menambahkan tanggal ke akhir nama file.

    Samuel Dionne-Riel menunjukkan dalam komentar bahwa ada cara yang jauh lebih baik untuk menangani referensi variabel kami.

    Argumen dipisahkan oleh spasi dalam bash shell, argumen akan memecah ketika ada ruang dalam perintah diperluas yang dihasilkan. Dalam naskah Anda, cp $ 1 $ 2. $ date_formatted akan berfungsi sebagaimana dimaksud selama variabel yang diperluas tidak memiliki spasi di dalamnya. Jika Anda memanggil skrip Anda dengan cara ini: datecp "nama lama saya" "nama baru saya" ekspansi akan menghasilkan perintah ini: cp nama baru saya nama lama saya. tanggal yang sebenarnya memiliki 6 argumen.

    Untuk mengatasi masalah ini dengan benar, baris terakhir skrip harus: cp "$ 1" "$ 2. $ date_formatted"

    Seperti yang Anda lihat, mengubah baris skrip kami dari:

    cp -iv $ 1 $ 2. $ date_formatted

    untuk:

    cp -iv "$ 1" "$ 2". $ date_formatted

    akan mengatasi masalah ini saat menggunakan skrip pada file yang memiliki spasi dalam namanya. Samuel juga menegaskan bahwa ketika menyalin dan menempelkan kode dari situs ini (atau internet secara umum) pastikan untuk mengganti tanda hubung yang tepat dan tanda kutip untuk yang "lebih baik secara tipografi" yang sering menggantikannya. Kami juga akan melakukan lebih banyak untuk memastikan kode kami lebih ramah copy / paste. ;-)

    Komentator lain, Myles Braithwaite, memutuskan untuk memperluas skrip kami sehingga tanggal akan muncul sebelum ekstensi file. Jadi, bukannya

    tastyfile.mp3.07_14_11-12.34.56

    kami akan mendapatkan ini:

    tastyfile.07_14_11-12.34.56.mp3

    yang akhirnya menjadi sedikit lebih nyaman bagi sebagian besar pengguna. Kodenya tersedia di halaman GitHub-nya. Mari kita lihat apa yang dia gunakan untuk memisahkan nama file.

    date_formatted = $ (tanggal +% Y-% m-% d_% H.% M% S)
    file_extension = $ (echo “$ 1" | awk -F. 'print $ NF')
    file_name = $ (basename $ 1. $ file_extension)

    cp -iv $ 1 $ file_name- $ date_formatted. $ file_extension

    Saya telah mengubah sedikit format, tetapi Anda dapat melihat bahwa Myles mendeklarasikan fungsi tanggalnya di Baris 1. Namun, di Baris 2, ia menggunakan perintah "echo" dengan argumen pertama dari skrip untuk menampilkan nama file. Dia menggunakan perintah pipa untuk mengambil output itu dan menggunakannya sebagai input untuk bagian selanjutnya. Setelah pipa, Myles memanggil perintah "awk", yang merupakan program pemindaian pola yang kuat. Menggunakan flag -F, dia memberi tahu perintah bahwa karakter selanjutnya (setelah spasi) adalah apa yang akan mendefinisikan "pemisah bidang". Dalam hal ini, itu adalah titik.

    Sekarang, awk melihat file bernama "tastyfile.mp3" yang terdiri dari dua bidang: "tastyfile" dan "mp3". Terakhir, dia menggunakan

    'print $ NF'

    untuk menampilkan bidang terakhir. Jika file Anda memiliki beberapa periode - karenanya membuat awk melihat banyak bidang - itu hanya akan menampilkan yang terakhir, yang merupakan ekstensi file.

    Di Baris 3, ia membuat variabel baru untuk nama file dan menggunakan perintah "nama bas" untuk referensi semuanya dalam $ 1 kecuali ekstensi file. Ini dilakukan dengan menggunakan nama samaran dan memberinya $ 1 sebagai argumennya, kemudian menambahkan spasi dan ekstensi file. Ekstensi file ditambahkan secara otomatis karena variabel yang mereferensikan Baris 2. Apa yang akan dilakukan adalah mengambil

    tastyfile.mp3

    dan mengubahnya menjadi

    makanan enak

    Kemudian di baris terakhir, Myles mengumpulkan perintah yang akan menampilkan semuanya secara berurutan. Perhatikan bahwa tidak ada referensi ke $ 2, argumen kedua untuk skrip. Skrip khusus ini akan menyalin file tersebut ke direktori Anda saat ini. Kerja bagus, Samuel dan Myles!

    Menjalankan Script dan $ PATH

    Kami juga menyebutkan dalam artikel Dasar kami bahwa skrip tidak diizinkan untuk dirujuk sebagai perintah secara default. Artinya, Anda harus menunjuk ke jalur skrip untuk menjalankannya:

    ./naskah

    ~ / bin / skrip

    Tapi, dengan menempatkan skrip Anda di ~ / bin /, Anda bisa mengetikkan nama mereka dari mana saja untuk menjalankannya.

    Komentator menghabiskan waktu untuk memperdebatkan seberapa tepat hal ini, karena tidak ada distro Linux modern yang membuat direktori itu secara default. Selain itu, tidak ada yang menambahkannya ke variabel $ PATH secara default, yang merupakan apa yang diperlukan agar skrip dijalankan seperti perintah. Saya agak bingung karena setelah memeriksa variabel $ PATH saya, komentatornya benar, tetapi skrip panggilan masih berfungsi untuk saya. Saya menemukan alasannya: banyak distro Linux modern membuat file khusus di direktori home pengguna - .profile.

    File ini dibaca oleh bash (kecuali .bash_profile ada di direktori home pengguna) dan di bagian bawah, ada bagian yang menambahkan folder ~ / bin / ke variabel $ PATH jika ada. Jadi, misteri itu hilang. Untuk sisa seri ini, saya akan terus menempatkan skrip di direktori ~ / bin / karena skrip pengguna dan harus dapat dijalankan oleh pengguna. Dan, tampaknya kita tidak benar-benar perlu mengacaukan variabel $ PATH dengan tangan untuk menyelesaikannya.

    Perintah berulang dengan loop

    Mari kita menuju ke salah satu alat paling berguna di gudang geek untuk menangani tugas yang berulang: loop. Hari ini, kita akan membahas loop "untuk".

    Garis besar dasar untuk-loop adalah sebagai berikut:

    untuk VARIABEL di LIST; melakukan
    command1
    perintah2
    ...
    perintah
    selesai

    VARIABEL dapat berupa variabel apa saja, meskipun paling sering huruf kecil "i" digunakan oleh konvensi. LIST adalah daftar item; Anda dapat menentukan beberapa item (memisahkannya dengan spasi), menunjuk ke file teks eksternal, atau menggunakan tanda bintang (*) untuk menunjukkan file apa pun di direktori saat ini. Perintah-perintah yang tercantum diindentasi oleh konvensi, sehingga lebih mudah untuk melihat bersarang - menempatkan loop dalam loop (sehingga Anda dapat mengulang sementara Anda loop).

    Karena daftar menggunakan spasi sebagai pembatas - yaitu, spasi menandakan perpindahan ke item berikutnya dalam daftar - file yang memiliki spasi dalam namanya tidak terlalu ramah. Untuk saat ini, mari kita tetap bekerja dengan file tanpa spasi. Mari kita mulai dengan skrip sederhana untuk menampilkan nama-nama file di direktori saat ini. Buat skrip baru di folder ~ / bin / Anda yang berjudul "loopscript". Jika Anda tidak ingat bagaimana melakukan ini (termasuk menandainya sebagai executable dan menambahkan hash bang hack) lihat artikel dasar-dasar scripting bash kami.

    Di dalamnya, masukkan kode berikut:

    untuk saya di item1 item2 item3 item4 item5 item6; melakukan
    gema "$ i"
    selesai

    Ketika Anda menjalankan skrip, Anda harus mendapatkan item-item daftar sebagai output.

    Cukup sederhana, bukan? Mari kita lihat apa yang terjadi jika kita sedikit mengubah segalanya. Ubah skrip Anda sehingga tertulis ini:

    untuk saya di *; melakukan
    gema "$ i"
    selesai

    Ketika Anda menjalankan skrip ini di folder, Anda harus mendapatkan daftar file yang dikandungnya sebagai output.

    Sekarang, mari kita ubah perintah gema menjadi sesuatu yang lebih berguna - katakanlah, perintah zip. Yaitu, kami akan menambahkan file ke dalam arsip. Dan, mari kita dapatkan beberapa argumen dalam campuran!

    untuk saya di $ @; melakukan
    arsip zip "$ i"
    selesai

    Ada sesuatu yang baru! "$ @" Adalah jalan pintas untuk "$ 1 $ 2 $ 3 ... $ n". Dengan kata lain, ini adalah daftar lengkap dari semua argumen yang Anda tentukan. Sekarang, perhatikan apa yang terjadi ketika saya menjalankan skrip dengan beberapa file input.

    Anda dapat melihat file mana yang ada di folder saya. Saya menjalankan perintah dengan enam argumen, dan setiap file ditambahkan ke arsip zip bernama "archive.zip". Mudah, benar?

    Untuk loop sangat indah. Sekarang Anda dapat menjalankan fungsi batch pada daftar file. Misalnya, Anda dapat menyalin semua argumen skrip Anda ke arsip zip, memindahkan dokumen asli ke folder lain, dan secara otomatis mengamankan menyalin file zip itu ke komputer jarak jauh. Jika Anda mengatur file kunci dengan SSH, Anda bahkan tidak perlu memasukkan kata sandi, dan Anda bahkan dapat memberitahu skrip untuk menghapus file zip setelah mengunggahnya!


    Menggunakan for-loop membuatnya mudah untuk melakukan banyak tindakan untuk semua file dalam direktori. Anda dapat menumpuk berbagai macam perintah secara bersamaan dan menggunakan argumen dengan sangat mudah untuk membuat dan membuat daftar sambil jalan, dan ini hanyalah puncak gunung es.

    Bash scripters, apakah Anda punya saran? Sudahkah Anda membuat skrip yang bermanfaat yang menggunakan loop? Ingin membagikan pendapat Anda tentang serial ini? Tinggalkan beberapa komentar dan bantu pemula scripting lainnya!