![运行存档脚本 (.tar) 而不将其保存在磁盘上,但无法识别其中的命令](https://linux22.com/image/15691/%E8%BF%90%E8%A1%8C%E5%AD%98%E6%A1%A3%E8%84%9A%E6%9C%AC%20(.tar)%20%E8%80%8C%E4%B8%8D%E5%B0%86%E5%85%B6%E4%BF%9D%E5%AD%98%E5%9C%A8%E7%A3%81%E7%9B%98%E4%B8%8A%EF%BC%8C%E4%BD%86%E6%97%A0%E6%B3%95%E8%AF%86%E5%88%AB%E5%85%B6%E4%B8%AD%E7%9A%84%E5%91%BD%E4%BB%A4.png)
在 CentOS 中,我想运行一个存档为 .tar 文件的脚本,但是当我尝试执行此操作时,它无法识别“读取”命令。
主要思想是运行这个脚本不保存在磁盘上
- 列出内容或 .tar 文件
tar -tf script.rar
- 返回它:
teste-1.sh
[user@host]$ tar -tf script.rar
teste-1.sh
解压文件,或解压文件并尝试执行它
tar -xvf script.rar | xargs bash
- 退货
your full info is:
[user@host]$ tar -xvf script.rar | xargs bash
your full info is:
[user@host]$ tar -xvf script.rar | bash -
bash: line 1: teste-1.sh: command not found
[user@host]$ tar -xvf script.rar | sh -
sh: line 1: teste-1.sh: command not found
如上所示,输出是代码的最后一行,并且不显示读取提示。仅用于测试目的的完整简单代码是:
#!/bin/bash
read -p "type your name:" name
read -p "type lastname:" lastname
echo "your full info is: $name $lastname"
当我尝试手动执行它时,它可以正常工作(无需存档)
[user@host]$ ./teste-1.sh
type your name:jhon
type lastname:doe
your full info is: jhon doe
- 我尝试过使用
| sh -
,| bash -
,但没有成功。有谁有有趣的想法吗?非常感谢!
答案1
在
cmd1 | xargs cmd2
xargs
获取 的输出cmd1
,将其拆分为单词(空格分隔,以自己的方式理解引号),并cmd2
使用这些单词作为参数进行调用。
使用tar -xvf somearchive
,tar
提取磁盘上的存档成员。因此-v
,它确实也会产生一些输出,但根据实现的不同,这些输出将出现在 stdout 或 stderr 上,并且不同实现之间的格式也会有很大差异。因此,xargs bash
要么在其标准输入上看不到任何内容,要么在一种或另一种格式中看不到存档成员列表。
因此xargs
将调用bash
不带参数的任一方法(然后bash
将解释在 stdin¹ 上输入的空脚本,因此不执行任何操作)。
对于仅在标准输出上输出存档成员的 tar 实现-v
,将调用bash teste-1.sh
(现在标准输入为空)。假设tar
在完成提取存档之前不关闭其标准输出,则teste-1.sh
在开始时将已将其完全提取到磁盘上bash
,因此bash
应该能够打开并解释脚本。
在这里,如果您不想将文件提取到磁盘上,则需要传递内容teste-1.sh
存档成员的值在bash
其标准输入上,而不是xargs
解释bash
其中的代码:
tar -xOf somearchive teste-1.sh | bash
(-O
一些tar
实现支持tar
将提取的成员的内容转储到其标准输出上,而不是在磁盘上创建文件)。
我们正在传递要提取的存档成员的名称,因为您可能不想传递多个脚本供 bash 解释。请注意,归档成员的名称必须完全按照 列出的方式传递tar tf
。
假设test-1.sh
脚本不读取其标准输入。如果是这样,它还会读取 bash 脚下的脚本(本身!)的内容。在上述其他情况下,脚本不会读取任何内容,因为输入为空。
避免这种情况的一种方法是将其称为:
bash <(tar -xOf somearchive test-1.sh)
这次,脚本的内容就像从命名管道传递到 bash 一样,因此 stdin 不受影响。
取决于xargs
实现, in xargs cmd
,的输入要么与(所以这里是空管道)cmd
相同,要么(也是空的)xargs
/dev/null