【问题标题】:Bash sub script redirects input to /dev/null mistakenlyBash 子脚本错误地将输入重定向到 /dev/null
【发布时间】:2017-06-03 06:09:35
【问题描述】:

我正在编写一个脚本来自动创建 .gitconfig 文件。

这是我的主脚本,它调用一个函数,该函数又执行另一个文件。

dotfile.sh

COMMAND_NAME=$1
shift
ARG_NAME=$@

set +a

fail() {
  echo "";
  printf "\r[${RED}FAIL${RESET}] $1\n";
  echo "";
  exit 1;
}

set -a

sub_setup() {
  info "This may overwrite existing files in your computer. Are you sure? (y/n)";
  read -p "" -n 1;
    echo "";
    if [[ $REPLY =~ ^[Yy]$ ]]; then
    for ARG in $ARG_NAME; do
      local SCRIPT="~/dotfiles/setup/${ARG}.sh";
      [ -f "$SCRIPT" ] && echo "Applying '$ARG'" && . "$SCRIPT" || fail "Unable to find script '$ARG'";
    done;
  fi;
}

case $COMMAND_NAME in
  "" | "-h" | "--help")
    sub_help;
    ;;
  *)
    CMD=${COMMAND_NAME/*-/}
    sub_${CMD} $ARG_NAME 2> /dev/null;
    if [ $? = 127 ]; then
      fail "'$CMD' is not a known command or has errors.";
    fi;
    ;;
esac;

git.sh

git_config() {
  if [ ! -f "~/dotfiles/git/gitconfig_template" ]; then
    fail "No gitconfig_template file found in ~/dotfiles/git/";
  elif [ -f "~/dotfiles/.gitconfig" ]; then
    fail ".gitconfig already exists. Delete the file and retry.";
  else
    echo "Setting up .gitconfig";

    GIT_CREDENTIAL="cache"

    [ "$(uname -s)" == "Darwin" ] && GIT_CREDENTIAL="osxkeychain";

    user " - What is your GitHub author name?";
    read -e GIT_AUTHORNAME;
    user " - What is your GitHub author email?";
    read -e GIT_AUTHOREMAIL;
    user " - What is your GitHub username?";
    read -e GIT_USERNAME;

    if sed -e "s/AUTHORNAME/$GIT_AUTHORNAME/g" \
    -e "s/AUTHOREMAIL/$GIT_AUTHOREMAIL/g" \
    -e "s/USERNAME/$GIT_USERNAME/g" \
    -e "s/GIT_CREDENTIAL_HELPER/$GIT_CREDENTIAL/g" \
    "~/dotfiles/git/gitconfig_template" > "~/dotfiles/.gitconfig"; then
      success ".gitconfig has been setup";
    else
      fail ".gitconfig has not been setup";
    fi;
  fi;
}

git_config

在控制台中

$ ./dotfile.sh --setup git
[ ?? ] This may overwrite existing files in your computer. Are you sure? (y/n)
y
Applying 'git'
Setting up .gitconfig
[ .. ]  - What is your GitHub author name?

然后我看不到我在输入什么...

dotfile.sh 的底部,我将函数调用期间发生的任何错误重定向到/dev/null。但我通常应该看到我正在输入的内容。如果我从这条线sub_${CMD} $ARG_NAME 2> /dev/null; 中删除2> /dev/null,它会起作用!!但我不明白为什么。

我需要这一行来防止我的脚本在我的命令不存在的情况下回显错误。我只想要我自己的信息。

例如

$ ./dotfile --blahblah
./dotfiles: line 153: sub_blahblah: command not found
[FAIL] 'blahblah' is not a known command or has errors

我真的不明白为什么我的子脚本中的输入被重定向到/dev/null,因为我提到只有stderr 被重定向到/dev/null

谢谢

【问题讨论】:

  • ARG_NAME=$@ 错了,错了,错了。 for arg in "$@"; do.
  • 扩展 chepner 的评论:如果您确实需要存储参数,请使用 arg_names=("$@")for arg in "${arg_names[@]}"。此外,您确实应该有明确的 shebang 行来使脚本使用 bash 而不是通用 shell 运行(即以 #!/bin/bash 启动每个脚本)。
  • 其实我有Shebang。我只是忘了把它贴在这里。感谢您的提示。添加这条无用的行只是不好的做法还是出于其他原因是错误的?
  • 我说的是 Args,而不是 shebang。
  • @eakl 它将参数粘在一起,它们之间没有任何明确的分隔符。如果任何参数包含空格(这是完全合法的,即使在文件名中也是如此),它们将被误认为是多个文件名。此外,当您使用不带双引号的变量时,除了按空格(以及制表符和换行符)拆分外,任何包含 shell 通配符的“单词”都将扩展为匹配文件名的列表。这导致了一些非常奇怪的错误......

标签: bash stdin file-descriptor stderr io-redirection


【解决方案1】:

您的read 语句中是否需要-e 选项?

我在交互式 shell 中进行了快速测试。以下命令不回显字符:

read -e TEST 2>/dev/null

以下确实会回显字符

read TEST 2>/dev/null

【讨论】:

    猜你喜欢
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    相关资源
    最近更新 更多