如何在没有替换或解释的情况下将字符串文字存储到变量中?

hav*_*ked 3 shell variable

要扁平化目录结构,我可以这样做:

find . -type f -exec sh -c 'mv "{}" "./`basename "{}"`"'  \;
Run Code Online (Sandbox Code Playgroud)

我想将以下内容作为 $FLATTEN 存储在我的个人资料中

-exec sh -c 'mv "{}" "./`basename "{}"`"'  \;
Run Code Online (Sandbox Code Playgroud)

这样以后我就可以执行 find . $FLATTEN

我在存储变量时遇到问题,因为它过早地被解释。我希望将它存储为字符串文字,并且仅在 shell 上使用时进行解释,而不是在来源时进行解释。

Sté*_*las 9

如果使用 GNU mv,您应该这样做:

find . -type f -exec mv -t . {} +
Run Code Online (Sandbox Code Playgroud)

与其他mvs:

find . -type f -exec sh -c 'exec mv "$@" .' sh {} +
Run Code Online (Sandbox Code Playgroud)

你永远不应该嵌入{}sh代码。这是一个命令注入漏洞,因为文件的名称被解释为 shell 代码(例如尝试使用一个名为的文件`reboot`)。

对于引用命令替换好一点,但由于您使用的是古老的形式(`...`而不是$(...)),你需要躲避内双引号或将在不工作sh的实现基于Bourne shell或AT&T的ksh(其中"`basename "foo bar"`"会实际上被视为"`basename "(具有`在这些 shell 中被接受的不匹配)与foo和 then连接bar"`")。

此外,当您执行以下操作时:

mv foo/bar bar
Run Code Online (Sandbox Code Playgroud)

如果bar确实存在并且是一个目录,那实际上是一个mv foo/bar bar/bar. mv -t . foo/bar或者mv foo/bar .没有那个问题。

现在,要将这几个参数 ( -exec, sh, -c, exec mv "$@" ., sh, {}, +) 存储到变量中,您需要一个数组变量。支持数组的外壳是(t)csh, ksh, bash, zsh, rc, es, yash, fish

并且为了能够直接使用该变量$FLATTEN(而不是"${FLATTEN[@]}"在 ksh/bash/yash 或$FLATTEN:qin 中(t)csh),您需要一个具有合理数组实现的外壳:rc,esfish. 还zsh在这里,这些参数都不是空的。

rc/ es/ zsh

FLATTEN=(-exec sh -c 'exec mv "$@" .' sh '{}' +)
Run Code Online (Sandbox Code Playgroud)

fish

set FLATTEN -exec sh -c 'exec mv "$@" .' sh '{}' +
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

find . -type f $FLATTEN
Run Code Online (Sandbox Code Playgroud)