Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何在bash中使用函数?_Linux_Bash_Unix_Awk_Openssl - Fatal编程技术网

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程序中都是一个很好的实践

基本规则是:函数的行为与任何其他命令类似:

  • 您可以重定向他们的输入/输出
  • 你可以用参数来调用它们
  • 就像
最好的功能类似于常见的unix可执行文件,例如从标准输入法读取数据并打印到标准输出法。这也允许您在管道中使用它们

那么,现在重写:

# 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=