Saya menemukan bahwa baris baru dihilangkan ketika saya melakukan "echo $ VAR". Sebaliknya, jika saya mengutip $ VAR, baris baru tersebut dipertahankan.
Brent
2
Itu tidak 100% benar. Substitusi perintah selalu menghapus baris baru yang tertinggal.
TheBonsai
7
Ini menciptakan subkulit; apakah ada cara untuk melakukannya di shell yang sama?
Penebusan Terbatas
24
Anda dapat menggunakan fungsi bash dalam perintah / pipelines seperti halnya Anda menggunakan program biasa. Fungsi ini juga tersedia untuk subkulit dan secara transitif, Substitusi Perintah:
VAR=$(scan)
Merupakan cara yang tepat untuk mencapai hasil yang Anda inginkan dalam banyak kasus. Saya akan menjelaskan kasus-kasus khusus di bawah ini.
Mempertahankan Garis Baru yang tertinggal:
Salah satu efek samping (biasanya membantu) dari Command Substitution adalah ia akan menghapus sejumlah baris baru yang tertinggal. Jika seseorang ingin mempertahankan garis baru yang tertinggal, seseorang dapat menambahkan karakter dummy ke keluaran subkulit, dan kemudian menghapusnya dengan perluasan parameter.
functionscan2 () {
local nl=$'\x0a'; # that's just \necho"output${nl}${nl}"# 2 in the string + 1 by echo
}
# append a character to the total output.# and strip it with %% parameter expansion.
VAR=$(scan2; echo"x"); VAR="${VAR%%x}"echo"${VAR}---"
cetakan (3 baris baru disimpan):
output
---
Gunakan parameter output: menghindari subkulit (dan mempertahankan baris baru)
Jika fungsi mencoba untuk mencapai adalah untuk "mengembalikan" string menjadi variabel, dengan bash v4.3 dan lebih tinggi, seseorang dapat menggunakan apa yang disebut a nameref. Namerefs memungkinkan suatu fungsi untuk mengambil nama dari satu atau lebih parameter output variabel. Anda dapat menugaskan sesuatu ke variabel nameref, dan itu seperti jika Anda mengubah variabel itu 'menunjuk ke / referensi'.
functionscan3() {
local -n outvar=$1# -n makes it a nameref.local nl=$'\x0a'
outvar="output${nl}${nl}"# two total. quotes preserve newlines
}
VAR="some prior value which will get overwritten"# you pass the name of the variable. VAR will be modified.
scan3 VAR
# newlines are also preserved.echo"${VAR}==="
cetakan:
output
===
Formulir ini memiliki beberapa keunggulan. Yakni, ini memungkinkan fungsi Anda untuk mengubah lingkungan pemanggil tanpa menggunakan variabel global di mana-mana.
Catatan: menggunakan nameref dapat meningkatkan kinerja program Anda jika fungsi Anda sangat bergantung pada bash bawaan, karena ini menghindari pembuatan subkulit yang dibuang setelahnya. Ini umumnya lebih masuk akal untuk fungsi kecil yang sering digunakan kembali, misalnya fungsi yang diakhiri denganecho "$returnstring"
yang localbuiltin akan menerima opsi bahwa declarebuiltin akan menerima. dari tes cepat, juga terlihat seolah-olah declare -ndalam lingkup fungsi juga memberikan ruang lingkup lokal variabel. sepertinya keduanya dapat dipertukarkan di sini.
Jawaban:
Cara yang persis sama untuk program.
sumber
Anda dapat menggunakan fungsi bash dalam perintah / pipelines seperti halnya Anda menggunakan program biasa. Fungsi ini juga tersedia untuk subkulit dan secara transitif, Substitusi Perintah:
Merupakan cara yang tepat untuk mencapai hasil yang Anda inginkan dalam banyak kasus. Saya akan menjelaskan kasus-kasus khusus di bawah ini.
Mempertahankan Garis Baru yang tertinggal:
Salah satu efek samping (biasanya membantu) dari Command Substitution adalah ia akan menghapus sejumlah baris baru yang tertinggal. Jika seseorang ingin mempertahankan garis baru yang tertinggal, seseorang dapat menambahkan karakter dummy ke keluaran subkulit, dan kemudian menghapusnya dengan perluasan parameter.
function scan2 () { local nl=$'\x0a'; # that's just \n echo "output${nl}${nl}" # 2 in the string + 1 by echo } # append a character to the total output. # and strip it with %% parameter expansion. VAR=$(scan2; echo "x"); VAR="${VAR%%x}" echo "${VAR}---"
cetakan (3 baris baru disimpan):
Gunakan parameter output: menghindari subkulit (dan mempertahankan baris baru)
Jika fungsi mencoba untuk mencapai adalah untuk "mengembalikan" string menjadi variabel, dengan bash v4.3 dan lebih tinggi, seseorang dapat menggunakan apa yang disebut a
nameref
. Namerefs memungkinkan suatu fungsi untuk mengambil nama dari satu atau lebih parameter output variabel. Anda dapat menugaskan sesuatu ke variabel nameref, dan itu seperti jika Anda mengubah variabel itu 'menunjuk ke / referensi'.function scan3() { local -n outvar=$1 # -n makes it a nameref. local nl=$'\x0a' outvar="output${nl}${nl}" # two total. quotes preserve newlines } VAR="some prior value which will get overwritten" # you pass the name of the variable. VAR will be modified. scan3 VAR # newlines are also preserved. echo "${VAR}==="
cetakan:
Formulir ini memiliki beberapa keunggulan. Yakni, ini memungkinkan fungsi Anda untuk mengubah lingkungan pemanggil tanpa menggunakan variabel global di mana-mana.
Catatan: menggunakan nameref dapat meningkatkan kinerja program Anda jika fungsi Anda sangat bergantung pada bash bawaan, karena ini menghindari pembuatan subkulit yang dibuang setelahnya. Ini umumnya lebih masuk akal untuk fungsi kecil yang sering digunakan kembali, misalnya fungsi yang diakhiri dengan
echo "$returnstring"
Ini relevan. https://stackoverflow.com/a/38997681/5556676
sumber
Saya pikir init_js harus menggunakan mendeklarasikan daripada lokal!
function scan3() { declare -n outvar=$1 # -n makes it a nameref. local nl=$'\x0a' outvar="output${nl}${nl}" # two total. quotes preserve newlines }
sumber
local
builtin akan menerima opsi bahwadeclare
builtin akan menerima. dari tes cepat, juga terlihat seolah-olahdeclare -n
dalam lingkup fungsi juga memberikan ruang lingkup lokal variabel. sepertinya keduanya dapat dipertukarkan di sini.