簡體   English   中英

傳遞給命令行參數時如何在Bash中轉義變量

[英]How to escape a variable in Bash when passing to a command-line argument

我有一個Bash腳本(Cygwin),該腳本使用一些Windows路徑,其中包含空格。 因此,我在變量定義中使用\\轉義了空格。

腳本中的所有內容都可以正常運行。 但是,我需要將此變量作為參數傳遞給命令行可執行文件。 當我這樣做時,我的逃脫變得一團糟。

示例非功能腳本:

#!/bin/sh

# File paths
destinationPath="/cygdrive/c/Documents and Settings/Eric/My Documents/"
attachments="\n2013-12-12.pdf"
body="Test Body"
recipient="asdf@asdf.com"


# Prepare attachments
args=""
for file in $attachments ; do
    file=${file//[ \\n]/}
    touch $file
    mv $file "$destinationPath/$file"
    args="$args -a $destinationPath/$file"
done


# Send email
echo -e $body | email --from-addr nosender@mydomain.com --from-name "Automated CSS Downloader" --subject "Downloaded new file(s) \
  from CSS" $args eric@mydomain.com

腳本的輸出:

$ bash -x test.sh
+ destinationPath='/cygdrive/c/Documents and Settings/Eric/My Documents/'
+ attachments='\n2013-12-12.pdf'
+ body='Test Body'
+ recipient=asdf@asdf.com
+ args=
+ for file in '$attachments'
+ file=2013-12-12.pdf
+ touch 2013-12-12.pdf
+ mv 2013-12-12.pdf '/cygdrive/c/Documents and Settings/Eric/My Documents//2013-12-12.pdf'
mv: listing attributes of `2013-12-12.pdf': Invalid argument
+ args=' -a /cygdrive/c/Documents and Settings/Eric/My Documents//2013-12-12.pdf'
+ echo -e Test Body
+ email --from-addr nosender@mydomain.com --from-name 'Automated CSS Downloader' --subject 'Downloaded new file(s) from CSS' -a /cygdrive/c/Documents and Settings/Eric/My Documents//2013-12-12.pdf eric@mydomain.com
email: WARNING: Email address 'and' is invalid. Skipping...
email: FATAL: Could not open attachment: /cygdrive/c/Documents: No such file or directory

因此,如您所見,路徑中的轉義空間未在$ args變量中導出。 我假設錯誤來自“ args = ...”行。 但是我不確定如何對$ destinationPath進行轉義以確保保留轉義的字符。

我試過在destinationPath中使用雙引號(無轉義空間),但無濟於事。 如果我嘗試在args =行中雙引號$ destinationPath,那么輸出也將被一堆額外的引號搞砸。

我該如何工作? 我嘗試過使用$ IFS變量,但是我真的不知道我在用它做什么,而且似乎也無法使其工作,盡管我懷疑解決方案與$有關。 IFS。

沒有數組就沒有很好的方法。 (使用eval並不是一種好方法,但是數組更簡單。)

問題是您希望每個文件最終都作為email一個參數,但是您想要將所有這些參數累加到Bash變量中。 完全沒有辦法:可以將Bash變量作為單個參數( "$arg" )插入,也可以將其插入,因為無論它分成多少單詞( $arg ),但是您無法根據創建變量時是否轉義空格來對它進行拆分,因為Bash僅記住分配給變量的字符串,而不記住轉義標記。

但是,您可以使用數組來完成此操作,因為您可以使每個文件名恰好是一個數組元素,並且可以讓Bash將數組作為每個元素的一個參數插入。

這是如何做:

# File paths                                                                                                                              
destinationPath="/cygdrive/c/Documents and Settings/Eric/My Documents/"
attachments="\n2013-12-12.pdf"
body="Test Body"
recipient="asdf@asdf.com"


# Prepare attachments                                                                                                             
args=()
for file in $attachments ; do
    file=${file//[ \\n]/}
    touch $file
    mv $file "$destinationPath/$file"
    args+=(-a "$destinationPath/$file")
done

# Send email                                                                                                                      
echo -e $body |
  email --from-addr nosender@mydomain.com \
        --from-name "Automated CSS Downloader" \
        --subject "Downloaded new file(s) from CSS" \
        "${args[@]}" eric@mydomain.com

您可能還需要將attachments變量設置為數組; 從出現換行符開始,我假設您實際上是在以某種更復雜的方式進行設置,所以我沒有更改代碼。 但是,如果附件名稱中有空格,您當前的代碼將無法工作(而且我很確定, for表單中的參數擴展將消除換行符,除非您更改了$IFS的值,因此file=${file//[ \\\\n]/}不必。)

在字符串中提供destinationPath時,需要轉義的雙引號引起來。

這應該工作:

#!/bin/sh                                                                                                                                 

# file paths                                                                                                                              
destinationPath="/cygdrive/c/Documents and Settings/Eric/My Documents/"
attachments="\n2013-12-12.pdf"
body="Test Body"
recipient="asdf@asdf.com"


        # prepare attachments                                                                                                             
        args=""
        for file in $attachments ; do
            file=${file//[ \\n]/}
            touch $file
            mv $file "$destinationPath/$file"
            #HERE YOU NEED ESCAPED DOUBLEQUOTED
            args="$args -a \"$destinationPath/$file\""
        done

        # send email                                                                                                                      
        echo -e $body | email --from-addr nosender@mydomain.com --from-name "Automated CSS Downloader" --subject "Downloaded new file(s) \
from CSS" $args eric@mydomain.com

暫無
暫無

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

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