コマンドで実行したときに文字列変数を参照できないのはなぜですか?

コマンドで実行したときに文字列変数を参照できないのはなぜですか?

私のUbuntu / DebianベースのLinuxアップデートPOSIXシェルスクリプトに必要なようです。二重引用符ではありません実行中の保存されたコマンドを含む文字列変数。この質問がわからないので理由を聞きたいです。コードが正しい場合はどうなりますか?

警告:SC2086、ウィキペディア、「二重引用符はワイルドカードとワードセパレータを防ぎます。」

スクリプトは次のようになり、問題のある部分を強調表示しました。

#!/bin/sh

# exit script when it tries to use undeclared variables
set -u

# color definitions
readonly red=$(tput bold)$(tput setaf 1)
readonly green=$(tput bold)$(tput setaf 2)
readonly yellow=$(tput bold)$(tput setaf 3)
readonly white=$(tput bold)$(tput setaf 7)
readonly color_reset=$(tput sgr0)
# to create blocks of texts, I separate them with this line
readonly block_separator='----------------------------------------'

step_number=0
execute_jobs ()
{
    while [ ${#} -gt 1 ]
    do
        job_description=${1}
        job_command=${2}

        step_number=$(( step_number + 1 ))

        printf '%s\n' "Step #${step_number}: ${green}${job_description}${color_reset}"

        printf '%s\n' "Command: ${yellow}${job_command}${color_reset}"

        printf '%s\n' "${white}${block_separator}${color_reset}"

        # RUN THE ACTUAL COMMAND
        # ShellCheck warns me I should double quote the parameter
        # If I did, it would become a string (I think) and I'd get 'command not found' (proven)
        # As I don't understand the issue, I left it as I wrote it, without quotes
        ### shellcheck disable=SC2086
        if sudo ${job_command} # <-- HERE
        then
            printf '\n'
        else
            printf '%s\n\n' "${red}An error occurred.${color_reset}"
            exit 1
        fi

        shift 2
    done
}

execute_jobs \
    'configure packages'                         'dpkg --configure --pending' \
    'fix broken dependencies'                    'apt-get --assume-yes --fix-broken install' \
    'update cache'                               'apt-get update' \
    'upgrade packages'                           'apt-get --assume-yes upgrade' \
    'upgrade packages with possible removals'    'apt-get --assume-yes dist-upgrade' \
    'remove unused packages'                     'apt-get --assume-yes --purge autoremove' \
    'clean up old packages'                      'apt-get autoclean'

ベストアンサー1

ここでは変数を参照できません。

if sudo ${job_command}

あなたのせいでする言葉を分割したい。引用すると、コマンドは(最初のステップの場合)になります。

if sudo "dpkg --configure --pending"

そして、エラーメッセージが示すように、引数と引数を持つコマンドではなくsudoコマンドを見つけます。dpkg --configure --pendingdpkg--configure--pending

sudo: dpkg --configure --pending: command not found

(より明確にするには、余分なスペースを試してください。)

引用符を省略すると、シェルは引数を分割し、すべてが期待どおりに機能します。

おすすめ記事