如何使用包含带空格的字符串的数组执行命令 linux
how to execute a command using array containing strings with spaces linux
关于 bash shell 数组,我已经被困在一个问题上几个小时了。
我正在使用从输入文件创建的字符串数组,使用 IFS=$'\n'
作为分隔符。
数组的每个索引可能包含多个由 space 分隔的单词。每个字符串代表 Options/Arguments 的组合,可用于执行另一个 shell 脚本。
我尝试将这些字符串提供给我使用以下语法的变体编写的另一个 shell 脚本:
# Run the testcases, case by case
for testcase in `cat $inputFile` ###"${testcases[@]}"
#for ((i = 0; i < ${#testcases[@]}; i++))
do
#testcase="${testcases[i]}"
# Print each case in inputFile
echo "${testcase}"
# Run the Archive Script, redirect output to /dev/null
./archive.sh "${testcase}" > /dev/null
# Respond to $# return value
done
您会注意到一些不同的变体,我曾用来循环遍历数组(或尝试通过直接从 cat
.
的输出中直接读入局部变量来直接响应
最令人沮丧的是 echo 命令有效,并打印带有 spaces 的字符串。但是,当我的脚本尝试使用字符串执行时,第一个单词被作为一个整体读取,但在第一个 space 之后,脚本尝试一次执行一个字符。 :(
请帮忙!这是我在执行脚本时得到的输出:
$ test_archive.sh lab6_testcase
Testcases Count: 6
Running cases:
-v dirA
./archive.sh: illegal option --
./archive.sh: illegal option -- d
./archive.sh: illegal option -- i
./archive.sh: illegal option -- r
./archive.sh: illegal option -- A
dirB
-v -r dirA
./archive.sh: illegal option --
./archive.sh: illegal option -- -
./archive.sh: illegal option -- r
./archive.sh: illegal option --
./archive.sh: illegal option -- d
./archive.sh: illegal option -- i
./archive.sh: illegal option -- r
./archive.sh: illegal option -- A
-v dirA dirB
./archive.sh: illegal option --
./archive.sh: illegal option -- d
./archive.sh: illegal option -- i
./archive.sh: illegal option -- r
./archive.sh: illegal option -- A
./archive.sh: illegal option --
./archive.sh: illegal option -- d
./archive.sh: illegal option -- i
./archive.sh: illegal option -- r
./archive.sh: illegal option -- B
dirc
-a
./archive.sh: illegal option -- a
TEST SUMMARY
SUCCESSFUL CASES:0
USAGE CASES:0
INVALID ARGUMENT CASES:6
-v dirA
dirB
-v -r dirA
-v dirA dirB
dirc
-a
这是完整的脚本,以防我错过了一些关键行触发和错误:
#!/bin/bash
# CONSTANTS
SUCCESS=0
USAGE_ERROR=1
INVALID_ARGUMENT=2
# Set the Input Field Seperator to '\n'
IFS=$'\n'
# Setup counters
usageErrorCount=0
argumentErrorCount=0
successCount=0
# Check if not enough or too many arguments have bee supplied
if (( $# != 1 ))
then
echo Usage: [=13=] filename
exit $USAGE_ERROR
fi
# Store the File in inputFile
inputFile=
# Check if the inputFile exists
if [[ ! -f $inputFile ]]
then
# Report that the file does not exist
echo "Exiting: The input file '$inputFile' does not exist!"
exit $INVALID_ARGUMENT
fi
# Read the lines from the file, and place them in the array
testcases=( `cat $inputFile` )
echo Testcases Count: ${#testcases[@]}
# Inform use of case list
echo Running cases:
# Run the testcases, case by case
for testcase in `cat $inputFile` ###"${testcases[@]}"
#for ((i = 0; i < ${#testcases[@]}; i++))
do
#testcase="${testcases[i]}"
# Print each case in inputFile
echo "${testcase}"
# Run the Archive Script, redirect output to /dev/null
./archive.sh "${testcase}" > /dev/null
# Use Switch Statement on ENV Success Var (#?) to:
# 1. Increment counters
# 2. Add testcase to appropriate array
case $? in
$USAGE_ERROR) # Add testcase to usage array
usageCases[$usageErrorCount]="$testcase"
# Up Usage Count
usageErrorCount=$((usageErrorCount+1))
;;
$INVALID_ARGUMENT) # Add testcase to argument array
argumentCases[$argumentErrorCount]="$testcase"
# Up Argument Count
argumentErrorCount=$((argumentErrorCount+1))
;;
$INVALID_ARGUMENT) # Add testcase to success array
successCases[$successCount]="$testcase"
# Up Success Count
successCount=$(($successCount+1))
;;
esac
done
# Format the Output
echo "TEST SUMMARY"
# Report Successful Cases
echo "SUCCESSFUL CASES:$successCount"
for testcase in ${successCases[@]}
do
echo $testcase
done
# Report Ussage Cases
echo "USAGE CASES:$usageErrorCount"
for testcase in ${usageCases[@]}
do
echo $testcase
done
# Report Successful Cases
echo "INVALID ARGUMENT CASES:$argumentErrorCount"
for testcase in ${argumentCases[@]}
do
echo $testcase
done
# Exit with Success
exit $SUCCESS
./archive.sh "${testcase}"
您正在使用单个参数调用 archive.sh(嵌入白色 space)。这就是双引号的作用。双引号内的所有内容都是一个单词。
由于参数的第一个字符是破折号,archive.sh 将参数的其余部分(包括嵌入的 space)作为选项,并抱怨它们不是有效选项。
您想删除引号。 Demo.
问题是由于您的 IFS 仍设置为 $'\n'
,因此 ./archive.sh
将整行作为单个参数读取并试图理解字母。
将 IFS 改回 ' '
,问题应该消失了!
示例:
# Run the testcases, case by case
for testcase in "${testcases[@]}"
do
IFS=' '
echo "${testcase}"
./archive.sh "${testcase}" > /dev/null
done
经过一番挖掘,我找到了解决问题的方法。
问题是 shell 在 evaluating/dereferencing 变量(或数组值)的内容之前执行命令。
因此,必须使用 eval
强制 shell 取消引用 variable/array 并在执行 variable/array 的命令之前检索内容。
这是一个工作版本(直接从文件中读取):
for testcase in `cat $inputFile`
do
#testcase="${testcases[i]}"
# Print each case in inputFile
echo " ${testcase}"
# Run the Archive Script, redirect output to /dev/null
eval ./lab5.sh ${testcase} > /dev/null
... CONTINUE WITH SCRIPT ...
关于 bash shell 数组,我已经被困在一个问题上几个小时了。
我正在使用从输入文件创建的字符串数组,使用 IFS=$'\n'
作为分隔符。
数组的每个索引可能包含多个由 space 分隔的单词。每个字符串代表 Options/Arguments 的组合,可用于执行另一个 shell 脚本。
我尝试将这些字符串提供给我使用以下语法的变体编写的另一个 shell 脚本:
# Run the testcases, case by case
for testcase in `cat $inputFile` ###"${testcases[@]}"
#for ((i = 0; i < ${#testcases[@]}; i++))
do
#testcase="${testcases[i]}"
# Print each case in inputFile
echo "${testcase}"
# Run the Archive Script, redirect output to /dev/null
./archive.sh "${testcase}" > /dev/null
# Respond to $# return value
done
您会注意到一些不同的变体,我曾用来循环遍历数组(或尝试通过直接从 cat
.
最令人沮丧的是 echo 命令有效,并打印带有 spaces 的字符串。但是,当我的脚本尝试使用字符串执行时,第一个单词被作为一个整体读取,但在第一个 space 之后,脚本尝试一次执行一个字符。 :(
请帮忙!这是我在执行脚本时得到的输出:
$ test_archive.sh lab6_testcase
Testcases Count: 6
Running cases:
-v dirA
./archive.sh: illegal option --
./archive.sh: illegal option -- d
./archive.sh: illegal option -- i
./archive.sh: illegal option -- r
./archive.sh: illegal option -- A
dirB
-v -r dirA
./archive.sh: illegal option --
./archive.sh: illegal option -- -
./archive.sh: illegal option -- r
./archive.sh: illegal option --
./archive.sh: illegal option -- d
./archive.sh: illegal option -- i
./archive.sh: illegal option -- r
./archive.sh: illegal option -- A
-v dirA dirB
./archive.sh: illegal option --
./archive.sh: illegal option -- d
./archive.sh: illegal option -- i
./archive.sh: illegal option -- r
./archive.sh: illegal option -- A
./archive.sh: illegal option --
./archive.sh: illegal option -- d
./archive.sh: illegal option -- i
./archive.sh: illegal option -- r
./archive.sh: illegal option -- B
dirc
-a
./archive.sh: illegal option -- a
TEST SUMMARY
SUCCESSFUL CASES:0
USAGE CASES:0
INVALID ARGUMENT CASES:6
-v dirA
dirB
-v -r dirA
-v dirA dirB
dirc
-a
这是完整的脚本,以防我错过了一些关键行触发和错误:
#!/bin/bash
# CONSTANTS
SUCCESS=0
USAGE_ERROR=1
INVALID_ARGUMENT=2
# Set the Input Field Seperator to '\n'
IFS=$'\n'
# Setup counters
usageErrorCount=0
argumentErrorCount=0
successCount=0
# Check if not enough or too many arguments have bee supplied
if (( $# != 1 ))
then
echo Usage: [=13=] filename
exit $USAGE_ERROR
fi
# Store the File in inputFile
inputFile=
# Check if the inputFile exists
if [[ ! -f $inputFile ]]
then
# Report that the file does not exist
echo "Exiting: The input file '$inputFile' does not exist!"
exit $INVALID_ARGUMENT
fi
# Read the lines from the file, and place them in the array
testcases=( `cat $inputFile` )
echo Testcases Count: ${#testcases[@]}
# Inform use of case list
echo Running cases:
# Run the testcases, case by case
for testcase in `cat $inputFile` ###"${testcases[@]}"
#for ((i = 0; i < ${#testcases[@]}; i++))
do
#testcase="${testcases[i]}"
# Print each case in inputFile
echo "${testcase}"
# Run the Archive Script, redirect output to /dev/null
./archive.sh "${testcase}" > /dev/null
# Use Switch Statement on ENV Success Var (#?) to:
# 1. Increment counters
# 2. Add testcase to appropriate array
case $? in
$USAGE_ERROR) # Add testcase to usage array
usageCases[$usageErrorCount]="$testcase"
# Up Usage Count
usageErrorCount=$((usageErrorCount+1))
;;
$INVALID_ARGUMENT) # Add testcase to argument array
argumentCases[$argumentErrorCount]="$testcase"
# Up Argument Count
argumentErrorCount=$((argumentErrorCount+1))
;;
$INVALID_ARGUMENT) # Add testcase to success array
successCases[$successCount]="$testcase"
# Up Success Count
successCount=$(($successCount+1))
;;
esac
done
# Format the Output
echo "TEST SUMMARY"
# Report Successful Cases
echo "SUCCESSFUL CASES:$successCount"
for testcase in ${successCases[@]}
do
echo $testcase
done
# Report Ussage Cases
echo "USAGE CASES:$usageErrorCount"
for testcase in ${usageCases[@]}
do
echo $testcase
done
# Report Successful Cases
echo "INVALID ARGUMENT CASES:$argumentErrorCount"
for testcase in ${argumentCases[@]}
do
echo $testcase
done
# Exit with Success
exit $SUCCESS
./archive.sh "${testcase}"
您正在使用单个参数调用 archive.sh(嵌入白色 space)。这就是双引号的作用。双引号内的所有内容都是一个单词。
由于参数的第一个字符是破折号,archive.sh 将参数的其余部分(包括嵌入的 space)作为选项,并抱怨它们不是有效选项。
您想删除引号。 Demo.
问题是由于您的 IFS 仍设置为 $'\n'
,因此 ./archive.sh
将整行作为单个参数读取并试图理解字母。
将 IFS 改回 ' '
,问题应该消失了!
示例:
# Run the testcases, case by case
for testcase in "${testcases[@]}"
do
IFS=' '
echo "${testcase}"
./archive.sh "${testcase}" > /dev/null
done
经过一番挖掘,我找到了解决问题的方法。
问题是 shell 在 evaluating/dereferencing 变量(或数组值)的内容之前执行命令。
因此,必须使用 eval
强制 shell 取消引用 variable/array 并在执行 variable/array 的命令之前检索内容。
这是一个工作版本(直接从文件中读取):
for testcase in `cat $inputFile`
do
#testcase="${testcases[i]}"
# Print each case in inputFile
echo " ${testcase}"
# Run the Archive Script, redirect output to /dev/null
eval ./lab5.sh ${testcase} > /dev/null
... CONTINUE WITH SCRIPT ...