我编写了一个脚本来根据读入的输入列表更改文件所有权。我的脚本在名称中没有空格的目录上正常工作。但是,它无法更改名称中包含空格的目录上的文件。我还想将chown命令的输出捕获到文件中。有人可以帮忙吗?
这是我在ksh中的脚本:
#!/usr/bin/ksh
newowner=eg27395
dirname=/home/sas/sastest/
logfile=chowner.log
date > $dir$logfile
command="chown $newowner:$newowner"
for fname in list
do
in="$dirname/$fname"
if [[ -e $in ]]
then
while read line
do
tmp=$(print "$line"|awk '{if (substr($2,1,1) == "/" ) print $2; if (substr($0,1,1) == "/" ) print '})
if [[ -e $tmp ]]
then
eval $command \"$tmp\"
fi
done < $in
else
echo "input file $fname is not present. Check file location in the script."
fi
done
答案 0 :(得分:1)
eval正在剥离此行的引号
command="chown $newowner:$newowner"
为了让线路与空间一起使用,您需要提供反斜杠报价
command="chown \"$newowner:$newowner\""
这样eval实际运行的命令是
chown "$newowner:$newowner"
此外,您可能需要围绕此变量设置引用,但您需要调整语法
tmp="$(print "$line"|awk '{if (substr($2,1,1) == "/" ) print $2; if (substr($0,1,1) == "/" ) print '})"
要捕获输出,您可以添加2&gt;&amp; 1&gt; file.out其中file.out是文件的名称...为了让它在使用它时使用eval你需要反斜杠任何特殊字符,就像你需要反斜杠双引号一样< / p>
答案 1 :(得分:1)
其他几个错误:
date > $dir$logfile
- 未定义$dir
变量while IFS= read -r line
但是要回答你的主要问题,不要试图动态地建立命令:不要打扰$command
变量,不要使用eval
,并引用变量。
chmod "$newowner:$newowner" "$tmp"
答案 2 :(得分:1)
您的示例代码表明该列表是一个&#34; meta&#34; file:每个文件的列表,每个文件都有一个要更改的文件列表。当您只有一个文件时,可以删除while循环
当list是包含文件名的变量时,您需要echo "${list}"| while ...
目前还不完全清楚为什么你有时想从第三个字段开始。似乎有时你在文件名之前有两个单词并希望它们被忽略。当文件名也有空格时,在空格上剪切字符串会成为问题。解决方案是查找一个空格后跟斜杠:该空格不是文件名的一部分,可以删除该空间的所有内容。
newowner=eg27395
# The slash on the end is not really part of the dir name, doesn't matter for most commands
dirname=/home/sas/sastest
logfile=chowner.log
# Add braces, quotes and change dir into dirname
date > "${dirname}/${logfile}"
# Line with command not needed
# Is list an inputfile? It is streamed using "< list" at the end of while []; do .. done
while IFS= read -r fname; do
in="${dirname}/${fname}"
# Quotes are important
if [[ -e "$in" ]]; then
# get the filenames with a sed construction, and give it to chmod with xargs
# The sed construction is made for the situation that in a line with a space followed by a slash
# the filename starts with the slash
# sed is with # to avoid escaping the slashes
# Do not redirect the output here but after the loop.
sed 's#.* /#/#' "${in}" | xargs chmod ${newowner}:${newowner}
else
echo "input file ${fname} is not present. Check file location in the script."
fi
done < list >> "${dirname}/${logfile}"