Mengapa --text = “$ @” hanya meneruskan kata pertama?

9

Ketika saya menjalankan skrip berikut dengan beberapa argumen seperti arg1 arg2 arg3:

#!/bin/bash
zenity --entry --text="$@"

zenity menciptakan dialog entri dengan teks ini: "arg1" sedangkan saya berharap "arg1 arg2 arg3"

Jika saya menggunakan variabel seperti skrip berikut ini akan menampilkan semua argumen untuk teks entri.

#!/bin/bash
text="$@"
zenity --entry --text="$text"

Apa perbedaan antara skrip ini? Mengapa yang pertama hanya menggantikan $@argumen pertama?

Omid
sumber

Jawaban:

16

$@mengembang menjadi kata-kata yang terpisah (sedangkan $*mengembang menjadi satu kata), seperti yang dijelaskan dalam bashmanual . Jadi, ketika Anda menulis

zenity --text="$@"

itu berkembang menjadi

zenity --text="$1" "$2" "$3"

Namun, tugas variabel shell tidak mengalami pemisahan kata. Perhatikan bahwa pemisahan bidang / kata dihilangkan dalam daftar ekspansi untuk penugasan variabel dalam bashmanual . Perilaku ini konsisten dengan spesifikasi POSIX . Jadi, ketika Anda menulis

text="$@"

variabel textmendapatkan semua parameter posisi sebagai satu kata, setara dengan jika Anda telah menulis text="$*". Memang, ini adalah alasan kutip ganda sering tidak perlu dalam penugasan variabel. Kedua

text=$@

dan

text=$*

sangat aman.

Begitu,

text=$@
zenity --option="$text"

meluas "$text"ke satu kata, itulah sebabnya ini bekerja. Perhatikan bahwa --option="$@"ini hanya argumen normal untuk perintah zenity, dan bukan penugasan variabel shell, itulah sebabnya pemisahan kata terjadi di sini tetapi tidak di text=$@.

jw013
sumber
1
+1. Ini juga akan berfungsi: zenity --text="$*"- "$*"meluas ke satu kata.
glenn jackman
+1 untuk mengajari saya satu hal: man! = Dokumentasi. Saya harus mencari info bash, itu juga berisi bagian manual yang Anda tautkan.
manatwork
7

$@ diperluas setiap parameter dalam kata yang terpisah, menjadi

zenity --entry --text="arg1" "arg2" "arg3" # syntactically wrong for zenity

Gunakan $*sebagai gantinya untuk mengembangkannya dalam satu kata

zenity --entry --text="$*"

yang akan menjadi

zenity --entry --text="arg1 arg2 arg3" # syntactically correct for zenity
manatwork
sumber
Tolong
jelaskan
@ ChandraRavoori, Anda menangkap saya dengan itu. Menurut manual "Pemisahan kata tidak dilakukan, dengan pengecualian" $ @ "" dan "Jika ekspansi dikutip ganda terjadi dalam sebuah kata, ekspansi parameter pertama digabungkan dengan bagian awal kata aslinya, dan perluasan dari parameter terakhir digabungkan dengan bagian terakhir dari kata aslinya. ”, jadi saya berharap text="$@"untuk diperluas ke text="arg1" "arg2" "arg3", yang seharusnya gagal. Namun yang pasti bukan itu masalahnya.
manatwork
@ChandraRavoori Alasannya pemisahan bidang tidak terjadi dalam tugas variabel. Saya menjelaskan lebih rinci dalam jawaban saya .
jw013
@ jw013: Tetapi menurut Manual Referensi Bash , "$@" tidak mengalami pemisahan kata, bahkan dalam penugasan variabel.
ruakh
@ruakh Manual bash tidak mengatakan sejauh yang saya tahu. Apakah Anda memiliki penawaran?
jw013