2011-10-06 86 views
44

當我嘗試在Bash中使用read命令是這樣的:如何在Bash中使用讀命令?

echo hello | read str 
echo $str 

沒有呼應,而我認爲應該str包含字符串hello。任何人都可以幫助我理解這種行爲嗎?

回答

49

你的腳本命令中的read沒問題。但是,您在管道中執行它,這意味着它位於子shell中,因此它讀取的變量在父shell中不可見。您可以

  • 移動在子shell腳本的休息,太:

    echo hello | { read str 
        echo $str 
    } 
    
  • ,或者使用命令替換來獲取變量的值從子shell的

    str=$(echo hello) 
    echo $str 
    

    或稍微複雜一些的例子(抓取ls的第二個元素)

    str=$(ls | { read a; read a; echo $a; }) 
    echo $str 
    
+0

真棒例子!我不得不在OSX上稍微調整一下,在大括號內放置空格,在echo之後加一個分號,如下所示:str = $(ls | {read a; read a; echo $ a;}) –

+5

是「讀一個;讀一個;」需要*兩次*? – javadba

+0

@javadba:不需要兩次。給出的例子從'ls'返回* second *項。用一個'讀一個'你會得到第一個項目。不要問我回答者爲什麼選擇這個例子。 – Fritz

3

的價值消失,因爲讀命令在一個單獨的子shell中運行:Bash FAQ 24

-5

你需要管?

echo -ne "$MENU" 
read NUMBER 
+1

-1:你的'echo'和'read'命令沒有任何連接。 –

+0

這不好嗎?它的工作原理... – mmrtnt

+0

海報顯然需要一種自動方式來填充變量,而無需手動輸入。 –

33

其他慶典的替代品,不涉及一個子shell:

read str <<END    # here-doc 
hello 
END 

read str <<< "hello"  # here-string 

read str < <(echo hello) # process substitution 
+2

你也可以在這裏使用這個字符串的過程,比如'read ABC <<< $(echo'aaa bbb ccc')' – maxpolk

8

典型用法可能是:

i=0 
echo -e "hello1\nhello2\nhello3" | while read str ; do 
    echo "$((++i)): $str" 
done 

和輸出

1: hello1 
2: hello2 
3: hello3 
2

爲了把我的兩個美分:KSH,read荷蘭國際集團作爲是一個變量工作,因爲根據the IBM AIX documentation,KSH的read確實影響當前shell環境:

的讀取指令shell變量的設置會影響當前shell執行環境。

這只是導致我花了好幾分鐘弄清楚爲什麼與read結束一行代碼,我曾經使用過億萬倍AI​​X上沒有工作在Linux上...這是因爲KSH做保存到當前環境,而BASH不會!

0

另一個替代方法是使用printf函數。

printf -v str 'hello' 

此外,該構建體,通過使用單引號酌情的結合,有助於避免子shell和其他形式的內插引用的多逃逸的問題。

+0

如果你正在努力實現這一切,那麼你最好'str =' hello'。我認爲這裏的要點是將一個命令的輸出捕獲到一個變量中。 – mc0e

0

我真的只使用讀取「而」和做循環:

echo "This is NOT a test." | while read -r a b c theRest; do 
echo "$a" "$b" "$theRest"; done 

這是一個測試。
對於它的價值,我看到了建議總是使用-r與bash中的讀取命令。