我正在尝试在新的 tmux 窗口上执行命令。一个简单的控制台/终端 pdf 阅读器。该脚本需要参数,一个 PDF 文件,文件名可能包含空格。我试过这个:
#!/bin/bash
tmux new-window "pdftotext -layout -nopgbrk "${1}" - | less"
它适用于没有空格的文件,例如1.pdf
.我试过sh
代替bash
,,代替$1
,没有效果。"$1"
"${1}"
答案1
tmux new-window
将命令传递给 shell。这很好,你的命令是一个管道,你需要一个 shell 来处理它。但这意味着会有一个 shell 会将您的命令作为字符串,然后才解释它(就像这样sh -c
做)。
似乎tmux new-window
(例如)可以从它获得的多个参数ssh
为内部(在远程)shell 中构建一个命令字符串。ssh
对于这些工具,我还是更喜欢给出一个单一的论点。
您需要对该内壳进行报价;同时您需要引用解释脚本的外壳。换句话说,您需要制作整个 tmux 命令,因此在外壳替换$1
并删除引号之后,它不会按字面意思理解,传递给的字符串形成tmux new-window
一个 shell 命令,其中需要引用的所有内容都被正确引用内壳。
一个明显的想法是嵌入一些额外的引号。但这是有缺陷的:
# 有缺陷,不要tmux new-window "pdftotext -layout -nopgbrk \"${1}\" - | less"#也有缺陷,不要tmux 新窗口“pdftotext -layout -nopgbrk '${1}' - | less”
"
包含、$
、`
、\
或!
的参数'
将破坏一个命令和/或另一个命令。更糟糕的是,这会产生代码注入漏洞(即,对于不幸或流氓参数,您的脚本将执行部分参数作为 shell 代码)。
您的脚本使用 Bash。我们可以要求 Bash 本身扩展$1
为引用形式安全的方式。这是由Q
修饰语:
#!/bin/bash
tmux new-window "pdftotext -layout -nopgbrk ${1@Q} - | less"
无论$1
扩展成什么,外壳都会扩展${1@Q}
成看起来正确引用内壳的形式。