Bash kullanarak bir fonksiyonun çıktısını bir değişkene nasıl atayabilirim?


Yanıtlar:


145
VAR=$(scan)

Programlar için olduğu gibi tamamen aynı.


3
"Echo $ VAR" yaptığımda satırsonlarının kaldırıldığını keşfettim. Bunun yerine $ VAR'dan alıntı yapsaydım, yeni satırları korudu.
Brent

2
Bu% 100 doğru değil. Komut ikamesi her zaman son satırları çıkarır.
TheBonsai

7
Bu bir alt kabuk oluşturur; bunu aynı kabukta yapmanın bir yolu var mı?
Sınırlı Kefaret

24

Bash işlevlerini, normal programları kullanacağınız gibi komutlarda / ardışık düzenlerde kullanabilirsiniz. İşlevler ayrıca alt kabuklarda ve geçişli olarak Komut Değiştirme:

VAR=$(scan)

Çoğu durumda istediğiniz sonucu elde etmenin basit bir yoludur. Aşağıda özel durumları özetleyeceğim.

Sondaki Yeni Satırları koruma:

Komut Değiştirmenin (genellikle yararlı) yan etkilerinden biri, herhangi bir sayıdaki satırsonu satırlarını kaldırmasıdır. Biri son satırları korumak isterse, alt kabuğun çıktısına bir kukla karakter ekleyebilir ve daha sonra bunu parametre genişlemesiyle çıkarabilir.

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}---"

baskılar (3 yeni satır tutulur):

output


---

Bir çıktı parametresi kullanın: alt kabuktan kaçınma (ve yeni satırları koruma)

İşlevin başarmaya çalıştığı şey, bash v4.3 ve üstü ile bir dizgeyi bir değişkene "döndürmek" ise, kişi a adı verilen şeyi kullanabilir nameref. Namerefs, bir işlevin bir veya daha fazla değişken çıktı parametresinin adını almasına izin verir. Bir isim değişkenine şeyler atayabilirsiniz ve sanki 'işaret ettiği / başvurduğu' değişkeni değiştirmişsiniz gibi.

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}==="

baskılar:

output

===

Bu formun birkaç avantajı vardır. Yani, işlevinizin her yerde global değişkenler kullanmadan arayanın ortamını değiştirmesine izin verir.

Not: İşlevleriniz büyük ölçüde bash yerleşiklerine dayanıyorsa, namerefs kullanmak programınızın performansını büyük ölçüde artırabilir, çünkü hemen ardından atılan bir alt kabuğun oluşturulmasını engeller. Bu genellikle, sıklıkla yeniden kullanılan küçük işlevler için daha mantıklıdır, örneğinecho "$returnstring"

Bu önemlidir. https://stackoverflow.com/a/38997681/5556676


0

Bence init_js local yerine declare kullanmalı!

function scan3() {
    declare -n outvar=$1    # -n makes it a nameref.
    local nl=$'\x0a'
    outvar="output${nl}${nl}"  # two total. quotes preserve newlines
}

localyerleşik , yerleşiğin kabul edeceği tüm seçenekleri declarekabul edecektir. Hızlı bir testten, aynı zamanda declare -nbir işlev kapsamındaymış gibi görünür ve değişkene yerel kapsam da verir. Görünüşe göre burada değiştirilebilirler.
init_js
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.