bash标志,可选择从stdin或文件读取

问题描述 投票:0回答:1

我知道这可能是一个愚蠢的问题,但它让我难过。我正在尝试编写一个接受标志和一个可选变量的shell脚本。一份文件。如果传递文件,则从文件中读取。如果没有,它从标准输入读取。我知道有类似的问题,但我找不到我的具体问题的答案。

我在下面提供了一个示例来说明问题。为了简洁起见,我已经省略了一些部分(例如验证)。

我可以接受标志并从文件中读取。或者我可以选择接受变量(文件)并从文件中读取。如果没有传递文件,那么我们从stdin读取。出于某种原因,当我尝试将两者结合起来时(接受标志,读取可选文件默认为stdin)我得到一个错误。

这有效。

#!/bin/sh
set -eu

while IFS=, read -r f1 
do
  echo $f1
done <"${1:-/dev/stdin}"

我可以这样称呼它... ./test.sh <<< "testing123"或者这...... echo "testing123" | ./test.sh或者这...... ./test.sh foo.csv。所有返回testing123假设foo.csv包含testing123

这也有效。

#!/bin/sh
set -eu

while true
do
  case $1 in
    -h|--help)
      echo "-h"
      exit
      ;;
    --)
      shift
      break
      ;;
    -?*)
      echo "unknown"
      ;;
    *)
      break
  esac

  shift
done

while IFS=, read -r f1 
do
  echo $f1
done <"${1}"

我可以称之为./test.sh foo.csv或这个./test.sh -f foo.csv。第一种情况返回testing123,第二种情况返回

unknown
testing123

出于某种原因,这不起作用。我不明白我在这里缺少什么?

#!/bin/sh
set -eu

while true
do
  case $1 in
    -h|--help)
      echo "-h"
      exit
      ;;
    --)
      shift
      break
      ;;
    -?*)
      echo "unknown"
      ;;
    *)
      break
  esac

  shift
done

while IFS=, read -r f1 
do
  echo $f1
done <"${1:-/dev/stdin}"

像这样./test foo.csv称它返回testing123。像这样被称为./test -f foo.csv它返回

unknown
testing123

这样称呼:

echo "testing123" | ./test.sh

或这个

./test.sh <<< "testing123"

它返回

./test.sh: line 6: $1 unbound variable
linux bash shell optional-parameters
1个回答
1
投票

更改

while true

while [ $# -ne 0 ]

当你的参数用完时,你的代码会继续循环的下一次迭代,并尝试测试不存在的$1。由于您已完成set -eu,因此引用未设置的变量会导致错误并且脚本将中止。

© www.soinside.com 2019 - 2024. All rights reserved.