Bagaimana cara mengembalikan string dari fungsi bash yang berisi nama file dengan spasi?

1

Saya mencoba menulis fungsi yang mengembalikan string yang terdiri dari dua bagian:

  1. opsi beralih
  2. nama file dengan spasi.

Masalah saya adalah: Bagaimana cara mengutip agar dapat meneruskan hasilnya ke program lain?

#!/bin/bash
getOption() {
  echo "-C $1"
}
# prints first lines of man page of cp (copy) 
man $(getOption "$1") cp | head -10

Dalam sampel ini saya mencoba meneruskan file konfigurasi khusus man. Dengan asumsi snippet di atas dinamai run.sh, konfigurasi yang disesuaikan dinamai my man.confdan keduanya berada di direktori yang sama saya mendapatkan kesalahan ini:

$ ./run.sh "my man.conf"
my: No such file or directory
Warning: cannot open configuration file my
# output from man for man…

Seperti yang ditunjukkan glenn jackman : Saya kehilangan satu titik dokumen Bash

Akar masalah yang dijelaskan di atas adalah bahwa Anda memerlukan cara untuk mempertahankan setiap argumen sebagai kata yang terpisah, bahkan jika argumen itu berisi spasi. Harga tidak akan melakukannya, tetapi sebuah array akan melakukannya.

Jadi ruang dipertahankan saat memperbarui ke

#!/bin/bash

args=("")
addOption() {
  args+=(-C "$1")
  return 0
}

$(addOption "$1")
man "${args[@]}" cp | head -10
Stephan
sumber
Pertanyaan Anda tidak jelas ... Apa itu cp di baris terakhir?
Sepahrad Salour

Jawaban:

1

lihat BashFAQ / 050

Pada dasarnya, Anda perlu merestrukturisasi. Bahkan melewati kutipan kembali dari fungsi tidak akan berhasil. Ini

getOption() {
  echo "-C '$1'"
}

hanya akan mengarah ke pesan kesalahan cannot open configuration file 'my

Setelah Anda menggabungkan string yang berisi spasi putih ke string lain, Anda tidak bisa mengekstraksi string yang ditambahkan sebagai satu kesatuan.

Mengingat pertanyaan Anda, Anda harus melakukannya

man -C "$1" ...

Tapi saya curiga Anda ingin "run.sh" lebih kompleks dari yang Anda tunjukkan. Harap berikan detail lebih lanjut.

glenn jackman
sumber
Ya, maksud dari fungsi ini adalah untuk menambahkan opsi dan nama filenya secara kondisional. Hasil fungsi dapat menjadi bagian dari perintah dalam hal apa pun - karena ia memutuskan untuk opsi yang valid atau string kosong. Dan ya, saran Anda untuk menggunakan array berhasil.
Stephan
1

Anda tidak mengutip, Anda harus keluar dari spasi pada baris perintah, misalnya:

./run.sh my\ man.conf

Di sebagian besar shell, penyelesaian tab akan membantu melakukan ini untuk Anda.

Tentu saja, spasi dalam nama file dan direktori semi-jahat, dan perbaikan sebenarnya adalah dengan mencoba dan menghindarinya.

ps Saya pikir skrip Anda memiliki masalah lain selain hanya mendapatkan argumen yang tepat. . .

ernie
sumber
Ruang tidak jahat dan tidak perlu dihindari. Cara mengatasinya adalah menulis program yang tidak rusak :)
slhck
@ernie terima kasih atas tanggapan Anda. Sayangnya melarikan diri tidak membuat perbedaan: ./run.sh my\ man.conf= ./run.sh "my man.conf" Saya tahu contohnya buatan tapi pendek dan - saya harap - mudah untuk mereproduksi. Apa masalah lain yang Anda temukan dalam sampel?
Stephan