有可能变成一个if-statement吗?

时间:2021-10-20 09:13:09

I have a script that outputs about 10 lines every time if it run. The content of these lines varies.

我有一个脚本,每次运行时输出大约10行。这些线条的内容各不相同。

I would really like to be able to grep in the output and do different things depending on the output.

我非常希望能够在输出中加入grep,并根据输出来做不同的事情。

In pseudo this is what I would like to do

在pseudo中,我想这样做

cat /etc/password | \\
if [ grep "root" $STDOUT ]; then
   echo "root is found"

elif [ grep "nobody" $STDOUT ]; then
   echo "nobody is found"

fi

Here have I used cat /etc/password as an example, but it should be replaced with my scripts mentioned above.

这里我使用了cat /etc/password作为示例,但是应该用上面提到的脚本替换它。

The problem is, how do I get hold of the output from cat /etc/password in the if/elif conditions?

问题是,如何在if/elif条件下获得cat /etc/password的输出?

7 个解决方案

#1


6  

As @Benoit recommends, just use grep directly.

正如@Benoit所建议的,只需直接使用grep。

As @larsmans notes, you can avoid a double-read of the file by reading it into a variable once.

正如@larsmans指出的,您可以通过一次将文件读入变量来避免重复读取。

Given the availability of bash I'd do it like this:

考虑到bash的可用性,我将这样做:

password=$(< /etc/passwd)

if grep -q root <<< "$password" ; then
    echo root found
elif grep -q nobody <<< "$password" ; then
    echo nobody found
fi

One read of the file, one or two invocations of grep, no other processes or subshells launched.

一次读取文件,一次或两次调用grep,没有启动其他进程或子shell。

#2


3  

You just do :

你做的事:

if grep -q "root" /etc/passwd ; then
   ...
fi

which will play the ... commands if grep exit code is 0.

会播放…如果grep退出代码为0,则命令。

remember that \[ is a external command, probably located in /usr/bin/[ (normally it's a hard link to test and when invoked as [ it requires a matching ] argument). Also see the pitfalls page here, many of them deal are related to that command.

记住,\[是一个外部命令,可能位于/usr/bin/[(通常它是一个要测试的硬链接,当调用时,它需要一个匹配的参数)。还可以在这里看到缺陷页面,其中许多与该命令相关。

#3


3  

I'd suggest using awk:

我建议使用awk:

cat /etc/passwd | awk '/root/{ do something }/nobody/{ do something else }'

You can achieve the same in bash using an expression like:

您可以在bash中使用如下表达式来实现相同的结果:

cat /etc/passwd |
while read; do
  if echo "$REPLY" | fgrep root; then
    something
  fi
  if echo "$REPLY" | fgrep nobody; then
    something_else
  fi
done

However the pure bash solution is less efficient for large inputs because it runs separate instances of grep for every line.

但是,对于大型输入,纯bash解决方案效率较低,因为它对每一行运行grep的单独实例。

#4


1  

Piping into an if-statement is possible with subshells, but that solution will break since you're running two grep commands on the pipe, the first of which will exhaust it.

对于子shell,管道进入if语句是可能的,但是由于您在管道上运行两个grep命令,第一个命令将耗尽该解决方案。

The best solution in your case is probably to read /etc/passwd into a variable, then grep it:

在您的示例中,最好的解决方案可能是将/etc/passwd转换为一个变量,然后grep:

passwd=$(cat /etc/passwd)
if (echo $passwd | grep -q root); then
     echo "root found"
fi
if (echo $passwd | grep -q nobody); then
     echo "nobody found"
fi

#5


1  

Just use &&:

只使用& &:

grep -q root /etc/password && echo "root is found"

grep -q nobody /etc/password && echo "nobody is found"

#6


0  

In the general case, you could use a temporary file.

在一般情况下,可以使用临时文件。

t=$(mktemp -t passwd.XXXXXXXX)
trap 'rm $t' 0
trap 'exit 127' 1 2 3 5 15
cat >$t
for u in root nobody; do
  fgrep $u $t
done

The traps are to remove the temporary file afterwards.

这些陷阱将在之后移除临时文件。

As an aside, you can pipe to an if, but the first grepinside your conditional would already consume all of its standard input. It's more useful in situations like this:

顺便说一句,您可以将管道传输到if,但是条件语句中的第一个grepin已经消耗了它的所有标准输入。在这种情况下它更有用:

if $option_count ; then
    wc -l
else
    tac
fi <file

#7


0  

How about the following:

如何:

#!/bin/bash

if [ -z $1 ]; then
   echo Usage: $0 [UID to search for]
   exit 1;
fi

SEARCHID="$1"

function notFound() {
    echo NOT FOUND 
}

function found() {
    echo Found it
}

function main() {

    grep -i $SEARCHID /etc/passwd
    # Move $? to a variable 
    SEARCHRESULT=$?

    if [ "$SEARCHRESULT" != "0" ]; then
       notFound;
    else
       found;
    fi
}

# call main function
main

#1


6  

As @Benoit recommends, just use grep directly.

正如@Benoit所建议的,只需直接使用grep。

As @larsmans notes, you can avoid a double-read of the file by reading it into a variable once.

正如@larsmans指出的,您可以通过一次将文件读入变量来避免重复读取。

Given the availability of bash I'd do it like this:

考虑到bash的可用性,我将这样做:

password=$(< /etc/passwd)

if grep -q root <<< "$password" ; then
    echo root found
elif grep -q nobody <<< "$password" ; then
    echo nobody found
fi

One read of the file, one or two invocations of grep, no other processes or subshells launched.

一次读取文件,一次或两次调用grep,没有启动其他进程或子shell。

#2


3  

You just do :

你做的事:

if grep -q "root" /etc/passwd ; then
   ...
fi

which will play the ... commands if grep exit code is 0.

会播放…如果grep退出代码为0,则命令。

remember that \[ is a external command, probably located in /usr/bin/[ (normally it's a hard link to test and when invoked as [ it requires a matching ] argument). Also see the pitfalls page here, many of them deal are related to that command.

记住,\[是一个外部命令,可能位于/usr/bin/[(通常它是一个要测试的硬链接,当调用时,它需要一个匹配的参数)。还可以在这里看到缺陷页面,其中许多与该命令相关。

#3


3  

I'd suggest using awk:

我建议使用awk:

cat /etc/passwd | awk '/root/{ do something }/nobody/{ do something else }'

You can achieve the same in bash using an expression like:

您可以在bash中使用如下表达式来实现相同的结果:

cat /etc/passwd |
while read; do
  if echo "$REPLY" | fgrep root; then
    something
  fi
  if echo "$REPLY" | fgrep nobody; then
    something_else
  fi
done

However the pure bash solution is less efficient for large inputs because it runs separate instances of grep for every line.

但是,对于大型输入,纯bash解决方案效率较低,因为它对每一行运行grep的单独实例。

#4


1  

Piping into an if-statement is possible with subshells, but that solution will break since you're running two grep commands on the pipe, the first of which will exhaust it.

对于子shell,管道进入if语句是可能的,但是由于您在管道上运行两个grep命令,第一个命令将耗尽该解决方案。

The best solution in your case is probably to read /etc/passwd into a variable, then grep it:

在您的示例中,最好的解决方案可能是将/etc/passwd转换为一个变量,然后grep:

passwd=$(cat /etc/passwd)
if (echo $passwd | grep -q root); then
     echo "root found"
fi
if (echo $passwd | grep -q nobody); then
     echo "nobody found"
fi

#5


1  

Just use &&:

只使用& &:

grep -q root /etc/password && echo "root is found"

grep -q nobody /etc/password && echo "nobody is found"

#6


0  

In the general case, you could use a temporary file.

在一般情况下,可以使用临时文件。

t=$(mktemp -t passwd.XXXXXXXX)
trap 'rm $t' 0
trap 'exit 127' 1 2 3 5 15
cat >$t
for u in root nobody; do
  fgrep $u $t
done

The traps are to remove the temporary file afterwards.

这些陷阱将在之后移除临时文件。

As an aside, you can pipe to an if, but the first grepinside your conditional would already consume all of its standard input. It's more useful in situations like this:

顺便说一句,您可以将管道传输到if,但是条件语句中的第一个grepin已经消耗了它的所有标准输入。在这种情况下它更有用:

if $option_count ; then
    wc -l
else
    tac
fi <file

#7


0  

How about the following:

如何:

#!/bin/bash

if [ -z $1 ]; then
   echo Usage: $0 [UID to search for]
   exit 1;
fi

SEARCHID="$1"

function notFound() {
    echo NOT FOUND 
}

function found() {
    echo Found it
}

function main() {

    grep -i $SEARCHID /etc/passwd
    # Move $? to a variable 
    SEARCHRESULT=$?

    if [ "$SEARCHRESULT" != "0" ]; then
       notFound;
    else
       found;
    fi
}

# call main function
main