bash 脚本中的基本名称带有空格?

发布于 2024-12-01 16:20:59 字数 536 浏览 2 评论 0原文

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

#!/bin/bash

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

for ARG in "$@"
    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:

我在所有内容上都有很多引号,所以我不明白为什么这不是按预期工作。

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

I'm working on a bash script to create a new folder in /tmp/ using the name of a file, and then copy the file inside that folder.

#!/bin/bash

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

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

done

Behavior:

When I type in mymove "/home/me/downloads/my new file.zip" it shows this:

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

I have lots of quotes around everything, so I don't understand why this is not working as expected.

Also, I have the form loop in there in case there are multiple files. I want them all to be copied to the same folder, based on the first argument's basename.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

澉约 2024-12-08 16:20:59

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

MYBASENAME=$(basename "$1")

就足够了。您应该养成使用 $() 而不是反引号的习惯,因为 $() 嵌套更容易(顺便说一句,它是 POSIX,所有现代 shell 都支持它。)

PS:您应该尝试编写bash脚本。尝试编写 shell 脚本。区别在于没有 bashism、zshism 等。就像 C 语言一样,可移植性是脚本的一个理想特性,特别是如果它可以轻松实现的话。您的脚本不使用任何 bashism,因此我会编写 #!/bin/sh 。对于挑剔的人:是的,我知道,旧的 SunOS 和 Solaris /bin/sh 不理解 $(),但 /usr/xpg4/bin/ sh 是一个 POSIX shell。

In the case where the assignment is a single command substitution you do not need to quote the command substitution. The shell does not perform word splitting for variable assignments.

MYBASENAME=$(basename "$1")

is all it takes. You should get into the habit of using $() instead of backticks because $() nests more easily (it's POSIX, btw., and all modern shells support it.)

PS: You should try to not write bash scripts. Try writing shell scripts. The difference being the absence of bashisms, zshisms, etc. Just like for C, portability is a desired feature of scripts, especially if it can be attained easily. Your script does not use any bashisms, so I'd write #!/bin/sh instead. For the nit pickers: Yes, I know, old SunOS and Solaris /bin/sh do not understand $() but the /usr/xpg4/bin/sh is a POSIX shell.

逆光下的微笑 2024-12-08 16:20:59

问题是 $1

MYBASENAME="`basename $1`" 

没有被引用。使用这个代替:

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

The problem is that $1 in

MYBASENAME="`basename $1`" 

is not quoted. Use this instead:

MYBASENAME="$(basename "$1")"
烈酒灼喉 2024-12-08 16:20:59

您缺少一组引号!

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

这将解决你的问题。

You're missing one set of quotes!

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

That'll fix your problem.

人间☆小暴躁 2024-12-08 16:20:59

我只是复制 [已解决] mv:目标“文件名”不是目录;归功于原始响应者:

将其添加到脚本的开头。它改变了内部场
分隔符仅用于换行,并且您的脚本会将空格视为仅
从此又一个角色。

#!/bin/bash

IFS='
'

<your script>

此维基百科页面介绍了有关特殊 shell 变量的更多信息:内部字段分隔符

I am just copying what's from [SOLVED] mv: target `filename' is not a directory; credit to the original responder:

Add this to the start of your script. It changes the internal field
separator to a newline only, and your script will treat spaces as just
another character from then on.

#!/bin/bash

IFS='
'

<your script>

This Wikipedia page tells more about the special shell variable: Internal field separator.

逆夏时光 2024-12-08 16:20:59
MYBASENAME="`basename $1`"

应该将

MYBASENAME="`basename "$1"`"

$1 用双引号括起来 "$1"

MYBASENAME="`basename $1`"

should be

MYBASENAME="`basename "$1"`"

Wrap the $1 with double quotes "$1"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文