この問題があるようです。このコードは、私のスクリプトのbash連想配列の119行目で壊れています。コメントは申し訳なく思っていますが、私はbashスクリプティングには新しく親切です。これはコードです:Bash連想配列エラー
#!/bin/bash
# Aliases file
# Command usage: cpRecent/mvRecent -d {dirFrom},{dirTo} -n {numberofFiles} -e {editTheNames}
# Error codes
NO_ARGS="You need to pass in an argument"
INVALID_OPTION="Invaild option:"
NO_DIRECTORY="No directory found"
# Return values
fullpath=
directories=
numfiles=
interactive=
typeset -a files
typeset -A filelist
# Advise that you use relative paths
__returnFullPath(){
local npath
if [[ -d $1 ]]; then
cd "$(dirname $1)"
npath="$PWD/$(basename $1)"
npath="$npath/" #Add a slash
npath="${npath%.*}" #Delete .
fi
fullpath=${npath:=""}
}
__usage(){
wall <<End-Of-Message
________________________________________________
<cpRecent/mvRecent> -d "<d1>,<d2>" -n <num> [-i]
-d First flag: Takes two arguments
-n Second flag: Takes one argument
-i Takes no arguments. Interactive mode
d1 Directory we are reading from
d2 Directory we are writing to
num Number of files
________________________________________________
End-Of-Message
}
__processOptions(){
while getopts ":d:n:i" opt; do
case $opt in
d) IFS=',' read -r -a directories <<< "$OPTARG";;
n) numfiles=$OPTARG;;
i) interactive=1;;
\?) echo "$INVALID_OPTION -$OPTARG" >&2 ; return 1;;
:) echo "$NO_ARGS"; __usage; return 1;;
*) __usage; return 1;;
esac
done
}
__getRecentFiles(){
# Check some conditions
((${#directories[@]} != 2)) && echo "$INVALID_OPTION Number of directories must be 2" && return 2
#echo ${directories[0]} ${directories[1]}
# Get the full paths of the directories to be read from/written to
__returnFullPath "${directories[0]}"
directories[0]="$fullpath"
__returnFullPath "${directories[1]}"
directories[1]="$fullpath"
if [[ -z ${directories[0]} || -z ${directories[1]} ]]; then
echo $NO_DIRECTORY
return 3
fi
[[ numfiles != *[!0-9]* ]] && echo "$INVALID_OPTION Number of files cannot be a string" && return 4
#numfiles=$(($numfiles + 0))
(($numfiles == 0)) && echo "$INVALID_OPTION Number of files cannot be zero" && return 4
local num="-"$numfiles""
# Get the requested files in directory(skips directories)
if [[ -n "$(ls -t ${directories[0]} | head $num)" ]]; then
# For some reason using local -a or declare -a does not seem to split the string into two
local tempfiles=($(ls -t ${directories[0]} | head $num))
#IFS=' ' read -r -a tempfiles <<< "$string"
#echo ${tempfiles[@]}
for index in "${!tempfiles[@]}"; do
echo $index ${tempfiles[index]}
[[ -f "${directories[0]}${tempfiles[index]}" ]] && files+=("${tempfiles[index]}")
done
fi
}
####################################
# The problem is this piece of code
__processLines(){
local name
local answer
local dirFrom
local dirTo
if [[ -n $interactive ]]; then
for ((i=0; i< ${#files[@]}; i++)); do
name=${files[i]}
read -n 1 -p "Old name: $name. Do you wish to change the name(y/n)?" answer
[[ answer="y" ]] && read -p "Enter new name:" name
dirFrom="${directories[0]}${files[i]}"
dirTo="${directories[1]}$name"
fileslist["$dirFrom"]="$dirTo"
done
else
for line in $files; do
dirFrom="${directories[0]}$line"
echo $dirFrom # => /home/reclusiarch/Documents/test
dirTo="${directories[1]}$line"
echo $dirTo # => /home/reclusiarch/test
fileslist["$dirFrom"]="$dirTo" # This is the offending line
done
fi
}
###########################################################
cpRecent(){
__processOptions $*
__getRecentFiles
__processLines
for line in "${!filelist[@]}"; do
cp $line ${filelist[$line]}
done
echo "You have copied ${#fileList[@]} files"
unset files
unset filelist
return
}
mvRecent(){
__processOptions $*
__getRecentFiles
__processLines
for line in "${!filelist[@]}"; do
mv $line ${filelist[$line]}
done
echo "You have copied ${#fileList[@]} files"
unset files
unset filelist
return
}
cpRecent "$*"
私は多くのことを試しました。スクリプトを実行するには、
$ bash -x ./testing.sh -d "Documents,." -n 2
しかし、何も動いていないようにみえ: (bashの-xを使用した場合)エラーはこれです:
./testing.sh: line 119: /home/reclusiarch/Documents/test: syntax error: operand expected (error token is "/home/reclusiarch/Documents/test")
私は、コマンドライン上でそのセクションを実行すると、それが動作します:
$ typeset -A filelist
$ filelist["/home/reclusiarch/Documents/test"]=/home/reclusiarch/test
$ echo ${filelist["/home/reclusiarch/Documents/test"]}
/home/reclusiarch/test
ありがとうございます!
編集:私は念頭に置いているコードにスクリプトを落としてしまいましたが、それは実行されない可能性があります。繰り返しますが、テストしたい場合は、与えられたbashコマンドを実行できます。 (スクリプトは理想的にはユーザーの$ HOMEディレクトリにあります)。
編集:解決済み(Charles Duffy解決済み)どちらの名前が忘れていたのは簡単な間違いでした。
これを*最小*の例にする必要があります。あなたが投稿したコードのほとんどはあなたの問題とは無関係です。 – chepner
スクリプトを起動するには、コマンドラインを置くことができますか?とにかく、@chepnerが正しいです、必要最小限の表現に減らそう! – OscarAkaElvis
そして実際には、「wall」というメッセージが表示されますか?システムの他のユーザーは、1人があなたのスクリプトをいかに悪用したかについて聞いていないでしょう。 – chepner