在bash脚本中使用空格的basename?

cwd*_*cwd 19 unix linux bash shell scripting

我正在使用bash脚本在/ tmp /中使用文件名创建一个新文件夹,然后将该文件复制到该文件夹​​中.

#!/bin/bash

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

for ARG in "$@"
    do
        mv "$ARG" "/tmp/$MYBASENAME"

done
Run Code Online (Sandbox Code Playgroud)

行为:

当我输入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:
Run Code Online (Sandbox Code Playgroud)

我有很多关于一切的引用,所以我不明白为什么这不能按预期工作.

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

Jen*_*ens 18

在赋值是单个命令替换的情况下,您不需要引用命令替换.shell不会对变量赋值执行分词.

MYBASENAME=$(basename "$1")
Run Code Online (Sandbox Code Playgroud)

只需要一切.你应该养成使用$()而不是反引号的习惯,因为$()它更容易嵌套(它是POSIX,顺便说一下,所有现代的shell都支持它.)

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


Ulr*_*gel 5

问题是$1

MYBASENAME="`basename $1`" 
Run Code Online (Sandbox Code Playgroud)

没有引用。改用这个:

MYBASENAME="$(basename "$1")"
Run Code Online (Sandbox Code Playgroud)

  • +1 用于使用 $() 形式的命令替换。伙计们,除非您真的非常确定您将使用一个只有 bourne shell 的系统,否则为什么不将您的技术语法升级到 1993 年标准;-)!我敢打赌,你会毫不犹豫地使用 `sed -i`。但是在依赖于 bourne shell 或 100 个其他 gnu/linux-isms 的系统上,您不会找到 `sed -i`。祝你们好运。<End PetPeeveRant /> (2认同)