如何在#!/bin/sh中重写grep?

How to rewrite grep in #!/bin/sh?

我有以下 shell 脚本,无法编译:

#!/bin/sh

.....
.....


clean_up() {
  echo "Clean up"
  docker stop $KC_TEST_SVC
  docker stop $KC_NAME
  docker stop $POSTGRES_NAME
  docker network rm $KC_NETWORK

}

# Check network if exists, if not then create
docker network inspect $KC_NETWORK
if [ $? -eq 1 ]; then
  docker network create $KC_NETWORK
  if [ $? -eq 1 ]; then
    exit 1
  fi
fi

docker run -d --rm --name $POSTGRES_NAME \
  -e POSTGRES_DB=$POSTGRES_DB \
  -e POSTGRES_USER=$POSTGRES_USER \
  -e POSTGRES_PASSWORD=$POSTGRES_PW \
  --network=$KC_NETWORK \
  postgres:12.3

if [ $? -eq 1 ]; then
  exit 1
fi

docker build --build-arg STAGE=int --tag $KC_TAG .
if [ $? -eq 1 ]; then
  exit 1
fi

docker run -d --rm --name $KC_NAME \
  -e DB_VENDOR=POSTGRES \
  -e DB_ADDR=$POSTGRES_NAME \
  -e DB_DATABASE=$POSTGRES_DB \
  -e DB_USER=$POSTGRES_USER \
  -e DB_PASSWORD=$POSTGRES_PW \
  -e KEYCLOAK_USER=$KC_USER \
  -e KEYCLOAK_PASSWORD=$KC_PW \
  -e KEYCLOAK_LOGLEVEL=DEBUG \
  --network=$KC_NETWORK \
  $KC_TAG "-Dkeycloak.migration.action=import -Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=/opt/jboss/keycloak/import-dir -Dkeycloak.migration.strategy=OVERWRITE_EXISTING"

if [ $? -eq 1 ]; then
  exit 1
fi

# Wait until Keycloak get started
sleep 30

# Run test jetty service that is protected with Keycloak
docker run -d --rm --name $KC_TEST_SVC \
  -v $(pwd)/app:/app \
  --network $KC_NETWORK \
  hub.databaker.io/devops/jetty-keycloak:0.1.6
if [ $? -eq 1 ]; then
  exit 1
fi

# Request Tokens for credentials
KC_URL=http://$KC_SERVER/$KC_CONTEXT/realms/$KC_REALM/protocol/openid-connect/token
echo "Keycloak URL => $KC_URL"

echo "Test the client connection to Keycloak with user $KC_TEST_USER"
KC_RESPONSE=$(
  docker run --rm --network=$KC_NETWORK curlimages/curl:7.71.1 -X POST \
    -d "username=$KC_TEST_USER" \
    -d "password=$KC_TEST_PW" \
    -d "grant_type=password" \
    -d "client_id=$KC_TEST_CLIENT" \
    $KC_URL | docker run --rm -i stedolan/jq .
)

echo "Response from Keycloak $KC_RESPONSE"

if grep -q "error" <<< "$KC_RESPONSE"; then
  echo "++++++++Error+++++++++"
  exit 1
fi

KC_ACCESS_TOKEN=$(echo "$KC_RESPONSE" | docker run --rm -i stedolan/jq -r .access_token)
echo "Access token from KC => $KC_ACCESS_TOKEN"

echo "Make request to protected service"
SVC_URL=http://$KC_TEST_SVC:8080/api/health
SVC_RES=$(docker run --rm --network=$KC_NETWORK curlimages/curl:7.71.1 -v -k \
  -H "Authorization: Bearer $KC_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  $SVC_URL | docker run --rm -i stedolan/jq .status)

clean_up

echo "$SVC_RES"

if [ "$SVC_RES" != "I am healthy" ]; then
  echo "Test failed."
  exit 1
else
  echo "Test was successful. The service response $SVC_RES."
fi

它抱怨:

Syntax error: redirection unexpected

由于以下行:

if grep -q "error" <<< "$KC_RESPONSE"; then
  echo "++++++++Error+++++++++"
  exit 1
fi

#!/bin/sh不支持grep。如何改写?

#!/bin/sh更改为#!/bin/bash(ev.替换bash位置,which bash有助于找到bash的位置,并查看bash 已安装),或者您可能需要以可移植的方式重写脚本。在这种情况下,创建一个临时文件,将字符串放入该文件中,并将该文件重定向到 grep(使用单个 <),然后删除该临时文件。

这么长的描述,你明白为什么在bash中有一个扩展,另一方面,它几乎是一个语法糖:你可以很容易地做到这一点。

<<< 是此处的字符串,它是 bash 的扩展名。在 posix shell 中,只需通过管道传输数据即可。

if printf "%s\n" "$KC_RESPONSE" | grep -q "error"; then

不要做if [ $? -eq 1 ]; then,这很容易出错。做 if ! command; then。 (您可能想要研究 set -eu)。