2011-08-25 58 views
14

我正在使用bash脚本在/ tmp /中使用文件的名称创建一个新文件夹,然后将该文件复制到该文件夹​​中。基地名称与空格在bash脚本中?

#!/bin/bash 

MYBASENAME="`basename $1`" 
mkdir "/tmp/$MYBASENAME" 

for ARG in "[email protected]" 
    do 
     mv "$ARG" "/tmp/$MYBASENAME" 

done 

行为:

当我mymove "/home/me/downloads/my new file.zip"键入它显示了这个:

mkdir /tmp/my 
new 
file.zip 
mv: rename /home/me/downloads/my new file.zip to /tmp/my\nnew\nfile.zip: 

我有很多周围的一切报价,所以我不明白这是为什么不按预期工作。

另外,如果有多个文件,我在那里有表单循环。我想根据第一个参数的基本名称将它们全部复制到同一个文件夹中。

回答

12

如果赋值是单个命令替换,则不需要引用命令替换。 shell不会为变量赋值执行分词。

MYBASENAME=$(basename "$1") 

是所需要的。你应该养成使用$(),而不是反引号的习惯,因为$()巢更容易(这是POSIX,顺便说一句,和所有现代化的炮弹支持。)

PS:你应该尽量庆典脚本。尝试编写shell脚本。不同之处在于没有bashisms,zshisms等。就像C一样,可移植性是脚本的一个理想特性,特别是如果它可以轻松实现的话。你的脚本不使用任何bashisms,所以我会写#!/bin/sh。对于挑选者:是的,我知道,旧的SunOS和Solaris /bin/sh不明白$(),但/usr/xpg4/bin/sh是POSIX shell。

+0

我注意到很多默认的shell脚本使用sh而不是bash。我仍然无法分辨出太多差别,除了像echo \ c这样的东西来保持新行不出现。感谢您的提示和有用的答案。 – cwd

+0

使用echo \ c的便携方式是使用'printf',您只需在格式字符串中省略'\ n'。最经常使用的bashisms可以说是使用了数组变量,非POSIX语法(例如'[[...]]'用于测试,用于for((...))'的循环以及'select'构造。 – Jens

+0

这不适用于在我的macosx狮子(GNU bash,版本3.2.48(1) - 发布(x86_64-apple-darwin11) – rjha94

4

的问题是,在$1

MYBASENAME="`basename $1`" 

没有加引号。使用这个来代替:

MYBASENAME="$(basename "$1")" 
+2

+1使用$()形式的命令替换。除非你真的确信你会使用只有Bourne shell的系统,为什么不把你的技术语法升级到1993年的标准;-)!我敢打赌你没有考虑过就使用'sed -i'。但是,在依赖bourne shell或100个其他gnu/linux-isms的系统上,您不会找到'sed -i'。祝你们好运。 shellter

0
MYBASENAME="`basename $1`" 

应该

MYBASENAME="`basename "$1"`" 

包裹$1用双引号"$1"

2

你错过了一组引号!

MYBASENAME="`basename \"$1\"`" 

这将解决您的问题。

+0

你正在写一对引号和反斜杠:-) – Jens