簡體   English   中英

引用bash變量分配

[英]Quoting in a bash variable assignment

使用以下簡化的代碼提取:

DIR='a b'
mount_command="./mount.cpfs $loop $DIR -f $OPTS"
sudo $mount_command

跟蹤打開時執行此行:

+ sudo ./mount.cpfs /dev/loop0 a b -f -o default_permissions,allow_other,attr_timeout=0

但是沒有引用DIR ,因此ab作為不同的參數傳遞,而不是傳遞給./mount.cpfs

創建這樣的命令序列,然后將其擴展到以后的命令行中的最佳方法是什么?

請記住,代碼示例已簡化為核心問題,我在多個地方使用mount_command在此之前和之后進行了各種添加,並且DIR由用戶傳遞。 我嘗試了幾種分配給mount_command時引用DIR組合,以及嘗試使用數組的原始組合。

mount_command示例用法

mount_command="./mount.cpfs $loop $DIR -f $OPTS"
case "$MODE" in
    gdb)
        sudo gdb -return-child-result -x gdbbatch \
            --args $mount_command
        ;;
    normal)
        sudo $mount_command
        ;;
    valgrind)
        sudo valgrind --track-fds=yes --leak-check=full --malloc-fill=0x80 \
            --free-fill=0xff $mount_command
        ;;
    *)
        echo "Mode '$MODE' unknown"
        mounted=''
        exit 2
        ;;
esac

Update0

請測試您的建議,我認為解決方案並不簡單。

bash中最好的方法是使用數組。 該數組將分隔要分開的單詞,並在單個單詞內保留空格:

DIR='a b'
mount_command=(./mount.cpfs $loop "$DIR" -f $OPTS)
sudo "${mount_command[@]}"

擴展"${mount_command[@]}" ,每個元素都將作為sudo的單個參數擴展,即使它具有空格。

請注意我是如何引用"$DIR"而不是$OPTS ,因為您的$OPTS包含打算作為單獨的單詞傳遞給mount命令的多個單詞,但是$DIR應該保持在一起。 但是,您可以使用與mount_command相同的方式使OPTS成為數組,並將其擴展為"${OPTS[@]}"mount_command定義內:

DIR='a b'
OPTS=(-o default_permissions,allow_other,attr_timeout=0)
mount_command=(./mount.cpfs $loop "$DIR" -f "${OPTS[@]}")
sudo "${mount_command[@])"

在bash腳本中完成了許多命令構建之后,我發現數組要比試圖找出正確的引用(如果可能)將命令維護在一個簡單字符串中要好得多。

嘗試使用eval

給定以下腳本,稱為test

#!/bin/bash
# test

echo $1

如果我這樣做:

DIR='a b'
CMD=."/test \"$DIR\""
eval $CMD

輸出

a b

看到這個問題

DIR='a b'
OPTS='-o allow_other,attr_timeout=0'
mount_command="./mount.cpfs '$loop' '$DIR' -f '$OPTS'"
eval sudo $mount_command

這應該工作。 很難理解shell中的引用,因為它與其他語言有很大不同。

在這種情況下,您需要引用'$ DIR'變量(最好是所有可以包含空格的變量)。 這很清楚。 但是shell僅一次解釋字符串! 您需要使用命令eval指示它重新解釋。 如果沒有eval ,則變量$ mount_command會被擴展,但不會處理內部的引用。

您可以閱讀有關此內容的簡短文章: White Shell

嘗試

 mount_command="./mount.cpfs $loop \\"$DIR\\" -f $OPTS" 

嘗試以下方法:

DIR='a b'
#following line replaces space occurrences with "\ "
DIR=`echo $DIR | replace ' ' '\ '`
mount_command="./mount.cpfs $loop $DIR -f $OPTS"
sudo $mount_command

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM