Dalam skrip, jika saya memasukkan #!/bin/bash
di atas, ini akan berfungsi dengan baik:
cp directory/{foo,bar} destination
Namun, dengan sh, ini akan memberikan kesalahan 'tidak ada file atau direktori seperti itu'. Di sh, apakah ada cara lain untuk mencapai tujuan akhir yang sama dengan satu perintah?
Jawaban yang Diterima:
Seperti yang Anda amati, tidak semua shell mendukung ekspansi brace.
Cara 1:Dua jalur terpisah (yaitu, menulis awalan dua kali)
Jika tujuan Anda benar-benar hanya untuk melakukannya dalam satu perintah, cara sederhananya adalah:
cp directory/file1 directory/file2 destination
cp
perintah mendukung beberapa argumen sumber diikuti oleh argumen tujuan. Faktanya, itulah yang terjadi dengan perintah yang sesuai untuk Anda di Bash. Bash melakukan ekspansi brace, yang mengubah perintah yang telah Anda gunakan menjadi yang ditunjukkan di atas. Yaitu, ketika Anda menjalankan cp directory/{file1,file2} destination
di Bash, cp
perintah tidak pernah melihat kurung kurawal.
Perintah seperti itu sederhana dan mudah dimengerti. Saya sarankan untuk mempertimbangkannya.
Cara 2:Variabel untuk awalan
Tetapi jika tujuan Anda adalah untuk menghindari pengulangan sendiri, maka Anda mungkin memilih untuk tidak melakukannya seperti itu, terutama jika directory
sebenarnya adalah jalan yang panjang. Lagi pula, jika nanti Anda harus mengedit jalur di skrip, Anda harus membuat perubahan pada kedua kemunculan.
Anda dapat menyimpan directory
(atau apa pun, mungkin jalur yang lebih panjang) dalam variabel Shell:
dir='directory'
cp "$dir/file1" "$dir/file2" destination
$dir
adalah ekspansi parameter. Shell menggantinya dengan nilai yang disimpan dalam variabel dir
. Saat menggunakan perluasan parameter, Anda tidak boleh menghilangkan tanda kutip ganda—kecuali jika Anda ingin pemisahan bidang dan globbing dilakukan. (Ini juga berlaku untuk Bash.)
Itu dua perintah, tetapi jika tujuan Anda yang sebenarnya adalah untuk menghindari pengulangan, itu mungkin yang Anda inginkan. Anda bisa menulis
dir='directory'; cp "$dir/file1" "$dir/file2" destination
untuk menjadikannya “satu perintah”, tetapi itu tidak lebih pendek dan sedikit kurang mudah dibaca.
(Perhatikan bahwa Anda tidak bisa begitu saja menghapus ;
di sana. Hasil dari melakukan akan menjadi perintah yang terbentuk dengan baik, tetapi tidak akan melakukan apa yang Anda inginkan. Itu akan menjalankan cp
perintah, meneruskan variabel lingkungan yang disebut dir
dengan nilai directory
ke dalam cp
lingkungan komando. Karena ini adalah cangkang dan bukan cp
perintah, yang memperluas dir
, ini tidak akan berhasil.)
Cara 3:cd
ig ke awalan
Jika skrip Anda tidak melakukan hal lain setelah melakukan operasi ini, atau tidak peduli apa direktori saat ini untuk perintah selanjutnya, maka if destination
adalah jalur absolut , Anda dapat menggunakan:
cd directory
cp file1 file2 destination
Tapi saya tidak menyarankan itu untuk skrip kecuali skrip Anda melakukan tindakan selanjutnya yang mendapat manfaat dari dijalankan dari direktori itu, atau bisa lebih singkat atau sederhana ditulis ketika dijalankan dari direktori itu. Kecuali jika direktori tempat skrip dijalankan bermakna untuk tujuan skrip, mengandalkannya dapat membuat skrip lebih sulit untuk dipikirkan; selanjutnya, jika cd
perintah berhasil tetapi cp
perintah gagal, pesan kesalahan yang dihasilkan mungkin kurang dari sepenuhnya. Sebagai gantinya, saya menyebutkan teknik cd
ing ke direktori sumber karena ini adalah pola yang berguna untuk interaktif penggunaan cangkang.
(Seperti yang ditunjukkan Hannu, Anda dapat menyertakan sejumlah perintah bersama-sama di dalam (
)
untuk menjalankannya dalam subkulit, dan perubahan pada lingkungan shell, termasuk efek cd
, tidak akan bertahan setelah perintah dijalankan. Ini adalah teknik yang sangat berguna, dan itu adalah kelalaian substansial yang tidak saya sebutkan. Namun, perhatikan bahwa ini tidak mengurangi masalah apa pun yang berkaitan dengan memiliki jalur relatif untuk destination
.)
Perhatikan bahwa jika cd
perintah gagal, perintah lain biasanya masih akan berjalan. Ini dapat menyalin file berbeda yang tidak ingin Anda salin (jika ada file lain dengan nama yang sama di direktori tempat skrip dijalankan) atau menghasilkan pesan kesalahan yang membingungkan. Jadi, Anda dapat memilih:
cd directory && cp file1 file2 destination
&&
menyebabkan perintah kedua berjalan hanya jika perintah pertama berhasil. Perhatikan bahwa itu masih tidak membatalkan efek menjalankan perintah pertama. Setelah semuanya berjalan, Anda masih berada di directory
, kecuali jika Anda menjalankannya dalam subkulit dengan (
)
.