这当然有效。我可以运行./test1.sh cats
并且参数cats
被正确传递给ls
.
$ cat test1.sh
#!/bin/sh
ls -l $1
您能否告诉我如何使第二个示例(内容与第一个示例相同,但已加密)以相同的方式工作?密码是“密码”。 openssl
输出上面的脚本并ls -l
运行,但是如何将命令行参数传递给它?
$ cat test2.sh
#!/bin/sh
echo "U2FsdGVkX1/m01Eg0CvZ7DiBi5Nf81+JrCWfKIDI9WtbkTZIVLhZskkKIioVfbSe"|openssl enc -base64 -d -aes-256-cbc|sh $1
澄清一下,test2.sh
相当于
$ cat test3.sh
#!/bin/sh
printf '%s\n' '#!/bin/sh' 'ls -l $1' | sh $1
答案1
您在问题的早期版本中已经有了它 - 将-s
选项传递给sh
:
echo "U2FsdGVkX1/m01Eg0CvZ7DiBi5Nf81+JrCWfKIDI9WtbkTZIVLhZskkKIioVfbSe" | openssl enc -base64 -d -aes-256-cbc | sh -s "$1"
这告诉 shell 从标准输入读取命令,同时接受其命令行上的参数(在 后面-s
)作为来自标准输入的脚本代码的位置参数。当然,shell 变量应该始终被引用,除非您有充分的理由不这样做,并且从长远来看,将"@"
(所有参数)传递给 shell 可能更有用。
test1.sh
因此,在;中引用所有对 shell 变量的引用也是明智的。例如,
ls -l "$1"
第一个解决方案(上面介绍的)似乎适用于“正常”参数。但是,要处理以以下开头的参数的情况-
,最好做sh -s -- "$1"
(或 "$@"
)。例如,
#!/bin/sh
code="U2FsdGVkX1/m01Eg0CvZ7DiBi5Nf81+JrCWfKIDI9WtbkTZIVLhZskkKIioVfbSe"
echo "$code" | openssl enc -base64 -d -aes-256-cbc | sh -s -- "$@"
(我将加密的脚本放入变量中只是为了使命令行更短,因此它适合超级用户显示列)。
答案2
该脚本将要求输入密码,解密加密的脚本并使用传递给主脚本的第一个命令行选项运行它:
#!/bin/bash
bash <(
openssl enc -base64 -d -aes-256-cbc <<<'U2FsdGVkX1/m01Eg0CvZ7DiBi5Nf81+JrCWfKIDI9WtbkTZIVLhZskkKIioVfbSe'
) "$1"
这不使用#!
解密脚本的 - 行,但假设它可以正常运行bash
(并且它总是解密成功)。解密脚本被传递到bash
解密脚本通过openssl
调用时的进程替换以及第一个命令行参数
要将解密的脚本写入磁盘,仅在正确解密(使用其预期的解释器)时运行它,然后将其删除:
#!/bin/bash
tmpscript=$(mktemp)
trap 'rm -f "$tmpscript"' EXIT
if ! openssl enc -base64 -d -aes-256-cbc <<<'U2FsdGVkX1/m01Eg0CvZ7DiBi5Nf81+JrCWfKIDI9WtbkTZIVLhZskkKIioVfbSe' >$tmpscript
then
exit 1
fi
chmod +x "$tmpscript"
"$tmpscript" "$1"
如果您想将主脚本的所有命令行参数传递给解密的脚本,您应该将"$1"
上面的示例更改为"$@"
.双引号很重要,因为它们确保传递各个参数时不会因空格而分割,也不会进行文件名通配。