Shell脚本只有在从node.js运行时才应读取输入时挂起

时间:2018-01-29 20:53:48

标签: node.js bash

我有一个问题。当使用命令行执行bash文件时,我可以让它正常工作。它获取输入并将其导出到环境变量。

如何让它不挂起并在提示文件中执行该块?

提示文件

#!/bin/bash

echo "Enter your "
read  input
echo "You said: $input"

Node.js文件:

这是我的调用提示文件

的节点文件
              checkIntegration(result)
                .then(result => {
                  console.log(result, '123');
                  shell.exec('. prompt')
                })
            })

当我在我的shell中运行它时,我可以输入随后打印的信息:

$ . prompt
Enter your
Hello
You said: Hello

然而,当我从节点运行它时,我看到了提示但它不接受任何输入:

Multiple attempts at entering text with no response

如何让我的程序从节点的终端读取用户输入?

更新。 enter image description here

我的文件夹结构

checker.js

const {exec} = require('child_process');
var shell = require('shelljs');

function getPrompt() {
  shell.exec('. prompt');
}

getPrompt()

tokens.txt

GITLAB_URL
GITLAB_TOKEN
GITLAB_CHANNEL
GITLAB_SHOW_COMMITS_LIST
GITLAB_DEBUG
GITLAB_BRANCHES
GITLAB_SHOW_MERGE_DESCRIPTION
SLACK_TOKEN

提示

#!/bin/bash

SOURCE="$PWD"
SETTINGS_FILE="$SOURCE/tokens.txt"
SETTINGS=`cat "$SETTINGS_FILE"`

for i in ${SETTINGS[@]}
do
echo "Enter your " $i
read  input
if [[ ! -z "$input" ]]; then
  export "$i"="$input"
fi
done

2 个答案:

答案 0 :(得分:1)

您的read正试图从node的管道读取,而不是从TTY读取;由于Node从不写入该管道,read会挂起。要从TTY读取,请按如下所示修改脚本:

#!/bin/bash

# IMPORTANT: Ignore the stdin we were passed, and read from the TTY instead
exec </dev/tty

# Use a BashFAQ #1 "while read" loop

settings_file="$PWD/tokens.txt"
while read -r setting <&3; do
  printf 'Enter your %s: ' "$setting" >&2 # prompt w/ trailing newline
  IFS= read -r "$setting"                 # read directly to named variable
  export "$setting"                       # export that variable to the environment
done 3<"$settings_file"

echo "Loop is finished; printing current environment" >&2
env

请注意:

  • 我们在脚本顶部使用exec </dev/tty重新打开直接从TTY读取的脚本。

  • 我们将FD 3用于设置文件以使其与stdin不同,因此read -r "$setting"仍然从TTY读取(通过上面的重定向重新打开),而read -r setting <&3从文件中读取。

  • 我们正在使用BashFAQ #1 while read循环来迭代输入。这比尝试对变量进行字符串拆分以获取名称列表要少;见Why you don't read lines with for

  • 我们正在运行env,以便为输出提供我们对环境所做的更改的证据 - 这一点很重要,因为以下内容。

虽然即使从Node启动shell也可以读取TTY的输入,但是一旦shell退出,所有用上述代码进行的环境变量更改都将丢失 - 它在{ {1}}来电退货。如果要更改节点进程本身的环境变量,则需要使用节点原语来执行此操作。

根本不需要bash来执行此操作:

shell.exec()

答案 1 :(得分:-1)

我不熟悉node.js,但是阅读一些文档,看起来该命令应该是child_process.exec('. prompt')这只有在与提示脚本位于同一目录中时才有效。

或者,您可以尝试使用其他shell版本#!/bin/sh