Melewati variabel ke skrip bash yang menggunakan 'EOF' dan menganggap variabel tersebut literal [tertutup]


9

dalam skrip ini saya berakhir dengan "$ 1" disimpan ke file / test.

#!/bin/bash
cat > /test << 'EOF'
$1
EOF

kebenarannya adalah .. saya harus menyimpannya

'EOF'

sebagai 'EOF' karena argumen saya ($ 1) berisi tanda dolar.

tetapi saya perlu argumen itu untuk disimpan daripada $ 1


1
'Karena argumen saya ( $1) berisi tanda-tanda dolar.' Tidak jika mengacu pada parameter baris perintah pertama. Pergantian dilakukan sebelum script Anda dieksekusi. Anda harus menghindarinya di baris perintah.
goldilocks

Anda telah mengajukan beberapa pertanyaan terkait tentang tugas yang Anda lakukan ini, dan perkembangan pertanyaan menunjukkan bahwa Anda tidak benar-benar memahami apa yang sedang terjadi dan mungkin tidak memilih pendekatan yang paling mudah. Sulit untuk membantu Anda tanpa mengetahui apa yang Anda coba lakukan, jadi saya sarankan Anda mengajukan pertanyaan di mana Anda jelas menjelaskan tugas keseluruhan Anda dan tidak membatasi jawaban untuk menggunakan alat tertentu. Misalnya, jangan katakan "Saya ingin menggunakan catdan menyimpan tanda dolar", tetapi "Saya ingin memodifikasi httpd.confuntuk mengubah <beberapa pengaturan> dengan <cara ini>".
Gilles 'SO- stop being evil'

@Gilles, akhirnya saya memutuskan untuk menulis ke file lain melalui python dan kemudian menggunakan skrip bash untuk menulis file itu ke file asli yang telah diedit. proses ini jauh lebih mudah. cat / temp_file> $ 1
user72685

@Gilles, alasan mengapa pertanyaan saya tidak masuk akal adalah karena cara bash scripts menangani variabel yang diteruskan kepada mereka. ada terlalu banyak hal yang harus dihindari tetapi belum ada fitur untuk menyandikan dan memecahkan kode dengan cepat.
user72685

@Gilles, satu-satunya hal yang masuk akal bagi saya sedikit adalah base64 tetapi mengapa seseorang harus menyandikan barang-barang mereka untuk lolos ke skrip bash .. melarikan diri dan kemudian mencoba membangun kembali hal-hal dalam skrip bash .. seluruh tiga garis miring untuk menghindari backtick dan lain-lain. menurut saya seperti kode neraka
user72685

Jawaban:


15

Menindaklanjuti Anda pertanyaan sebelumnya , sepertinya Anda ingin baik beberapa teks uninterpreted dan beberapa teks ditafsirkan masuk ke sebuah file. Dalam hal ini, menggunakan dua yang berbeda cats (atau echos):

cat > /test <<'EOF'
some uninterpreted text $(pwd)
not substituted: $1
EOF
cat >> /test <<EOF
but this will substitute: $1
EOF

Ada beberapa hal yang terjadi di sini: pertama, sintaks heredoc dengan <<. Jika Anda menyertakan tanda kutip dalam string terminator, seperti pada yang pertama di atas, seluruh heredoc tidak diinterpretasikan - tidak ada parameter dan tidak ada substitusi. Jika Anda tidak menggunakan tanda kutip, seperti pada yang kedua di cat atas, variabel seperti $1akan digantikan oleh nilai-nilai mereka dan pergantian perintah akan dimasukkan dalam teks. Anda memilih antara apakah akan mengutip string "EOF" atau tidak berdasarkan pada apakah Anda ingin penggantian atau tidak.

Untuk memasukkan kedua cats ke file yang sama, kami menggunakan >> pengalihan untuk pengalihan kedua (dan yang lebih baru): itu berarti menambahkan ke file. Untuk yang pertama, kami menggunakan satu >untuk menghapus file dan mulai segar.

Perhatikan bahwa, bahkan ketika variabel disubstitusi , setiap dolar tambahan masuk dalam nilai variabel itu tidak diganti sendiri:

foo='$bar'
bar=hello
cat <<EOF
$foo
EOF

akan menampilkan:

$bar

tanpa mengganti $barnilai.

Namun, jika Anda memberikan "$" dalam argumen untuk keseluruhan skrip ini, Anda perlu menghindarinya di baris perintah atau melampirkan semuanya dalam tanda kutip tunggal. Sebagai alternatif, perintah substitusi seperti dalam pertanyaan Anda yang lain memungkinkan Anda meletakkan konten seluruh file secara langsung, termasuk tanda dolar dalam isi file. Pastikan Anda mengutip string pengganti di sana:

oo.sh "$(cat myfile)"

akan mendapatkan tubuh myfilesebagaimana $1dan kemudian catatau echosesuai kebutuhan. Batasan yang sama seperti pada jawaban saya di sana berlaku: ada batas untuk berapa lama argumen baris perintah bisa, dan jika file Anda mungkin lebih lama dari itu Anda harus menemukan pendekatan lain. Anda dapat mengetahui batas apa yang ada di sistem Andagetconf ARG_MAX


1

Kedengarannya seperti Anda hanya ingin menampilkan satu variabel ke file. Dalam hal ini, ini akan berhasil:

echo $1 >/test

Perhatikan bahwa /testada di direktori root, yang biasanya tidak memiliki izin tertulis untuk pengguna biasa.

EDIT: Ingatlah bahwa Anda perlu mengutip string yang mengandung tanda dolar di baris perintah . Di situlah substitusi terjadi, dan skrip tidak dapat berbuat apa-apa setelah fakta.


Saya pikir Anda memiliki jawaban yang benar sekarang. +1
goldilocks

@ MichaelHomer jawaban jauh lebih lengkap dan termasuk informasi berguna tentang dokumen di sini yang saya lupa Jawabannya harus diterima (kecuali orang lain memposting yang lebih baik, tentu saja).
Tom Zych
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.