Linux 如何在bash中使用函数?
我有一个文件,该文件将文件的哈希值与其文件名相对应。 比如说,Linux 如何在bash中使用函数?,linux,bash,unix,awk,openssl,Linux,Bash,Unix,Awk,Openssl,我有一个文件,该文件将文件的哈希值与其文件名相对应。 比如说, fb7e0a4408e46fd5573ffb9e73aec021a9dcf426235c0ccfc37d2f5e09a68a23 /path/to/some/file 237e0a4408e46fe3573f239e73aec021a9dcf426235c023fc37d2f5e09a68a12 /path/to/another/file ... and so on... 我需要将哈希转换为base64编码格式 所以我使用了bas
fb7e0a4408e46fd5573ffb9e73aec021a9dcf426235c0ccfc37d2f5e09a68a23 /path/to/some/file
237e0a4408e46fe3573f239e73aec021a9dcf426235c023fc37d2f5e09a68a12 /path/to/another/file
... and so on...
我需要将哈希转换为base64
编码格式
所以我使用了bash函数和awk
的组合
这是我写的
#!/bin/sh
base64Encode() {
$1 | openssl base64 -A
}
awk ' { t = base64Encode $1; print t } ' file.txt
但它似乎不起作用。我正在使用hashdeep
生成哈希列表文件,hashdeep
不支持base64
编码输出。这就是我使用openssl的原因
任何关于这方面的帮助或提示都将非常好
编辑:
给出的答案有效,但我似乎还有其他问题
通常cat filename | openssl dgst-sha256 | openssl base64-A
为filename
文件提供绝对正确的base64
编码输出,
和来自hashdeep
的输出匹配来自cat filename | openssl dgst-sha256
的输出。
因此,我考虑将从上述步骤获得的输出管道化到opensslbase64-A
,以获得base64
输出。但是,我仍然从实际结果中得到不同的值
虽然这可能适用于单独的问题,但我仍然希望得到任何支持。仅限Awk:
$ awk '{ c="echo " $1 "|openssl base64 -A"
c | getline r
print r }' file
ZmI3ZTBhNDQwOGU0NmZkNTU3M2ZmYjllNzNhZWMwMjFhOWRjZjQyNjIzNWMwY2NmYzM3ZDJmNWUwOWE2OGEyMwo=
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo=
对于紧凑型单衬里版本,请参见下文@123的注释
。。。和@EdMorton的超紧版本。由于您特别询问如何使用函数,我将问题分为几个小函数。这在所有(更大的)bash程序中都是一个很好的实践 基本规则是:函数的行为与任何其他命令类似:
- 您可以重定向他们的输入/输出
- 你可以用参数来调用它们
- 就像
# function for create base64 - reads from stdin, writes to stdout
base64Encode() {
openssl base64 -A
}
# function for dealing with your file
# e.g. reads lines "hash path" and prints "base64 path"
convert_hashes() {
while read -r hash path; do
b64=$(base64Encode <<< "$hash")
echo "$b64 $path"
done
}
#the "main" program
convert_hashes < your_file.txt
是的,我知道,我只想要base64
,不需要附加路径。当然,您可以修改上述convert_hash
并从输出中删除路径,例如,您可以使用echo“$b64$path”
而不是echo“$b64”
并且输出将仅是b64
字符串-但是您在函数中丢失了信息-哪个字符串属于哪个路径-imho,而不是最佳做法
因此,您可以将函数保持原样,并使用另一个工具来获取第一列(仅在需要时),例如在“main”程序中。这样你就设计了一个函数,为以后更通用的方式
convert_hashes < your_file.txt | cut -d ' ' -f1
现在想象一下,您扩展了脚本,不想使用文件,但输入来自另一个程序:让我们使用以下get_data
功能来模拟这一点(当然,在真正的应用程序中,它将执行其他操作,而不仅仅是cat
:
get_data() {
cat <<EOF
fb7e0a4408e46fd5573ffb9e73aec021a9dcf426235c0ccfc37d2f5e09a68a23 /path/to/some/file
237e0a4408e46fe3573f239e73aec021a9dcf426235c023fc37d2f5e09a68a12 /path/to/another/file
EOF
}
输出将与上述相同
当然,您也可以对输出做一些事情,比如说
get_data | convert_hashes | grep another/file | cut -d ' ' -f1
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo=
当然,如果您有这样的“模块化”结构,那么您可以轻松地更换任何部件,而无需触摸其他部件,比如用base64
命令替换openssl
base64Encode() {
base64
}
当然,在真正的应用程序中,只调用一个程序的函数(可能)是毫无意义的,但我特别这么做,因为你问了函数的问题
否则,可以简单地执行上述操作:
while read -r hash path; do
openssl base64 -A <<<"$hash"
echo
#or echo $(openssl base64 -A <<<"$hash")
#or printf "%s\n" $(openssl base64 -A <<<"$hash")
done < your_file.txt
Ps:老实说,我不明白为什么需要对一些已经编码的哈希进行base64编码-但是YMMV:)您希望得到什么输出?你不需要文件名吗?@123我会使用文件名,但我无法使
base64
编码工作。这只是一个演示代码。awk不是shell。不能从awk脚本调用shell函数,正如不能从awk脚本调用C函数一样,反之亦然。在这种情况下,与仅从shell调用shell函数相比,awk脚本对您完全没有任何帮助,因此-有什么理由不这样做吗?这是可行的,但我所做的仍然有错误。通常cat filename | openssl dgst-sha256 | openssl base64-A
为filename
文件提供绝对正确的base64
编码输出,并从hashdeep
输出与cat filename | openssl dgst-sha256
匹配的输出。因此,我考虑将从上述步骤获得的输出管道化到opensslbase64-A
,以获得base64
输出。但,我还是从实际结果中得到了不同的值。Stack Overflow是一个解决编程和开发问题的网站。这个问题似乎离题了,因为它与编程或开发无关。请参见帮助中心中的。也许或者会是一个更好的提问的地方。当然,see也可以做awk'{“echo”$1“| openssl base64-A“| getline}1”文件
@123,但它看起来太不规范了,我不得不将其分解。@123不,因为这样你就不能用close(c)
轻松地关闭管道。James-记住测试getline是否成功并关闭管道(if((c | getline)>0)r=line;else r=“N/A”;close(c)
),但当然在这种情况下awk对您没有任何帮助,因此您不会在如此简单的应用程序中真正使用它,您只需要使用一个shell脚本。@EdMorton为什么需要简单地关闭管道?一般来说,您必须关闭管道,以便在其输入流关闭时,右侧命令的进程可以终止,这样您就不会出现“打开太多管道”故障,因此您有两个选择:a)c=“echo”$1”| openssl base64-a;c | getline r;关闭(c)
或b)echo“$1”| openssl base64-A”| getline r;关闭(“echo“$1”| openssl base64-A”)
。显然,a
更可取,因此如果在错误的位置获得空格字符或命令stri与
get_data | convert_hashes | grep another/file | cut -d ' ' -f1
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo=
base64Encode() {
base64
}
while read -r hash path; do
openssl base64 -A <<<"$hash"
echo
#or echo $(openssl base64 -A <<<"$hash")
#or printf "%s\n" $(openssl base64 -A <<<"$hash")
done < your_file.txt
cut -d ' ' -f1 base | xargs -I% -n1 bash -c 'echo $(openssl base64 -A <<<"%")'
ZmI3ZTBhNDQwOGU0NmZkNTU3M2ZmYjllNzNhZWMwMjFhOWRjZjQyNjIzNWMwY2NmYzM3ZDJmNWUwOWE2OGEyMwo=
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo=