Я обнаружил, что новые строки удаляются, когда я сделал "echo $ VAR". Если вместо этого я процитировал $ VAR, он сохранил символы новой строки.
Brent
2
Это не на 100% верно. Подстановка команд всегда удаляет завершающие символы новой строки.
TheBonsai
7
Это создает подоболочку; есть ли способ сделать это в той же оболочке?
Limited Atonement
24
Вы можете использовать функции bash в командах / конвейерах, как и в обычных программах. Функции также доступны в подоболочках и, транзитивно, подстановке команд:
VAR=$(scan)
В большинстве случаев это простой способ добиться желаемого результата. Ниже я опишу частные случаи.
Сохранение завершающих символов новой строки:
Одним из (обычно полезных) побочных эффектов подстановки команд является то, что она удаляет любое количество завершающих символов новой строки. Если кто-то желает сохранить завершающие символы новой строки, можно добавить фиктивный символ к выводу подоболочки, а затем удалить его с помощью расширения параметров.
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}---"
печатает (сохранено 3 символа новой строки):
output
---
Используйте выходной параметр: избегайте подоболочки (и сохраняя новые строки)
Если функция пытается «вернуть» строку в переменную, то в bash v4.3 и выше можно использовать то, что называется a nameref. Namerefs позволяет функции принимать имя одного или нескольких выходных параметров переменных. Вы можете назначать вещи переменной nameref, и это как если бы вы изменили переменную, на которую она «указывает / ссылается».
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}==="
печатает:
output
===
У этой формы есть несколько преимуществ. А именно, он позволяет вашей функции изменять среду вызывающего без использования глобальных переменных повсюду.
Примечание: использование namerefs может значительно повысить производительность вашей программы, если ваши функции сильно зависят от встроенных функций bash, поскольку это позволяет избежать создания подоболочки, которая сразу после этого удаляется. Обычно это имеет смысл для небольших функций, которые часто используются повторно, например, функций, заканчивающихся наecho "$returnstring"
localвстроенный будет принимать какие - либо варианты , что declareвстроенная команда будет принимать. из быстрого теста также кажется, что declare -nв области видимости функции также предоставляется локальная область видимости переменной. кажется они здесь взаимозаменяемы.
Ответы:
Точно так же, как и для программ.
источник
Вы можете использовать функции bash в командах / конвейерах, как и в обычных программах. Функции также доступны в подоболочках и, транзитивно, подстановке команд:
В большинстве случаев это простой способ добиться желаемого результата. Ниже я опишу частные случаи.
Сохранение завершающих символов новой строки:
Одним из (обычно полезных) побочных эффектов подстановки команд является то, что она удаляет любое количество завершающих символов новой строки. Если кто-то желает сохранить завершающие символы новой строки, можно добавить фиктивный символ к выводу подоболочки, а затем удалить его с помощью расширения параметров.
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}---"
печатает (сохранено 3 символа новой строки):
Используйте выходной параметр: избегайте подоболочки (и сохраняя новые строки)
Если функция пытается «вернуть» строку в переменную, то в bash v4.3 и выше можно использовать то, что называется a
nameref
. Namerefs позволяет функции принимать имя одного или нескольких выходных параметров переменных. Вы можете назначать вещи переменной nameref, и это как если бы вы изменили переменную, на которую она «указывает / ссылается».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}==="
печатает:
У этой формы есть несколько преимуществ. А именно, он позволяет вашей функции изменять среду вызывающего без использования глобальных переменных повсюду.
Примечание: использование namerefs может значительно повысить производительность вашей программы, если ваши функции сильно зависят от встроенных функций bash, поскольку это позволяет избежать создания подоболочки, которая сразу после этого удаляется. Обычно это имеет смысл для небольших функций, которые часто используются повторно, например, функций, заканчивающихся на
echo "$returnstring"
Это актуально. https://stackoverflow.com/a/38997681/5556676
источник
Я думаю, что init_js должен использовать declare вместо local!
function scan3() { declare -n outvar=$1 # -n makes it a nameref. local nl=$'\x0a' outvar="output${nl}${nl}" # two total. quotes preserve newlines }
источник
local
встроенный будет принимать какие - либо варианты , чтоdeclare
встроенная команда будет принимать. из быстрого теста также кажется, чтоdeclare -n
в области видимости функции также предоставляется локальная область видимости переменной. кажется они здесь взаимозаменяемы.