Bash stdin - 我正在失去所有换行符



我有这个bash脚本来进行加密:

#!/bin/bash
#encrypt.sh
fn=$1
if [ $# -eq 0 ]
  then
    echo "Filename required..."
fi
echo "Type text. Hit Ctrl-d when done"
keyvariable=$(cat)
echo -e $keyvariable | gpg --symmetric --cipher-algo AES256 > $fn

我有这个脚本来解密:

#!/bin/bash
#decrypt.sh
fn=$1
if [ $# -eq 0 ]
  then
    echo "Filename required..."
fi
cat $fn | gpg --decrypt

示例:

sh encrypt.sh test

Type text. Hit Ctrl-d when done
hello
how
are


you
?

我输入密码并确认。好的,太好了。我现在有一个名为"test"的加密文件。

但当我去解密"测试"时,输出是:

sh decrypt test

gpg: AES256 encrypted data
gpg: encrypted with 1 passphrase
-e hello how are you ?

我正在丢失所有换行符!该怎么办?

<小时>

答案其实很简单:

echo -e "$keyvariable" | gpg --symmetric --cipher-algo AES256 > $fn

注意$keyvariable周围的引号。

就是这样!

在行中

echo -e $keyvariable | gpg --symmetric --cipher-algo AES256 > $fn

当扩展$keyvariable时,任何嵌入的空白(而不仅仅是换行符)都会用于将生成的字符串拆分为多个不同的单词。echo然后将每个字输出到标准输出,用单个空格分隔。新线只是最明显的"受害者";您可能会看到制表符(0x09)被空格替换,以及多个空格被缩减为一个空格。由于文件名的生成,还有其他字符可能会发生更改(此处的详细信息并不重要)。

解决方案是引用参数扩展:

echo -e "$keyvariable" | gpg --symmetric -cipher-algo AES256 > "$fn"

正如其他人所提到的,允许gpg直接从标准输入中读取更简单,而不是使用cat拦截击键并将其放入变量中。

echo "Type text. Hit Ctrl-d when done"
gpg --symmetric --cipher-algo AES256 > "$fn"

(实际上,gpg在直接从终端读取时(如图所示)与从管道读取(如从echo命令读取)的行为可能略有不同。这可以解释您被提示输入密码的原因。我认为解决方案是告诉gpg从标准输入读取,特别是添加"-"作为最后的论据,但请查阅您的手册页进行验证。也就是说,

gpg --symmetric --cipher-algo AES256 - > "$fn"

)

不要将其存储在变量中,然后将该变量回显到gpg中。通过管道。在您的设置中,您应该只通过gpg调用发送cat的输出,而不需要回声。

或者干脆不用cat!删除存储输入的行,并删除回波部分,使该行只读取

gpg --symmetric ...

问题不在于gpg,而在于bash和echo。您缺少引号。检查此脚本并查看差异。

s=$(printf "onentwo")
echo $s
echo "$s"