Bash 当一个函数从shell脚本用here文档调用时,它应该如何退出?

Bash 当一个函数从shell脚本用here文档调用时,它应该如何退出?,bash,shell,unix,cobol,heredoc,Bash,Shell,Unix,Cobol,Heredoc,我有一个COBOL程序,它应该通过shell脚本运行,并且应该接受here文档中的值。在here文档中,我应该调用一个函数,该函数应该让控件以退出代码异常退出 我尝试了以下方法,但对我无效 这是我的COBOL程序: 01 WW-ANS PIC X值空间。 IRS-200。 显示“上述答案是否正确?是/否”。 接受ws-ans。 display“输入的值是“ws-ans”“WW-ans”因为funexit是在由命令替换创建的子shell中执行的,所以您需要在here文档之外检查其退出状态,以确定父

我有一个COBOL程序,它应该通过shell脚本运行,并且应该接受here文档中的值。在here文档中,我应该调用一个函数,该函数应该让控件以退出代码异常退出

我尝试了以下方法,但对我无效

这是我的COBOL程序:

01 WW-ANS PIC X值空间。
IRS-200。
显示“上述答案是否正确?是/否”。
接受ws-ans。

display“输入的值是“ws-ans”“WW-ans”因为
funexit
是在由命令替换创建的子shell中执行的,所以您需要在here文档之外检查其退出状态,以确定父shell是否应该退出

#!/bin/bash
funexit () {
  echo "calling funexit"
  exit 1
}

output=$(funexit) || exit

/caplus/pub/test123<<:EOD:
1
g
$output
Y
:EOD:
!/bin/bash
funexit(){
回声“呼叫funexit”
出口1
}
输出=$(funexit)| |退出

/caplus/pub/test123将函数的输出分配给herdoc之外的变量,并在那里检查故障:

#!/bin/bash
funexit ()
{
    exit 1
}

if ! funexitvalue=$(funexit) ; then
    echo "Failure!"
    exit 1
fi


/caplus/pub/test123<<:EOD:
1
g
$funexitvalue
Y
:EOD:
如您所见,即使替换中的命令失败,第一个回显也会成功退出。命令替换的返回代码不会以任何方式影响实际命令

相比之下:

$ a="$(echo foobar; exit 1)"
$ echo $?
1
$ echo $a
foobar
在这里,命令替换的返回代码不受任何其他命令的影响,因此您可以实际检查它是否成功返回。无论如何,将输出分配给
a
仍然成功



注意:如果您打算将COBOL程序运行到错误输入发生的点,那么heredoc就不是办法,因为它们在被传递到程序之前已经被完全评估过了。因此,对于heredoc,它是一个全有或全无的处理。

heredoc将被shell解析并作为输入传递到它的e中你的方法是行不通的。但是,你当然可以分解输入:

{ cat << EOF
This text will always be entered to the test123 executable;
EOF
funexit  # exit or return, as needed
cat << EOF
If funexit returned, this will go to test123.
If funexit exited, it will not
EOF
} | caplus/pub/test123

{cat这个例子看起来很做作,因为你给了它两个静态输入。然而,这可能是因为这只是一个简化的例子

我猜您希望funexit返回E,这样输入就意味着没有更多的输入,如果有更多的输入,就什么也没有了。更清楚的是,funexit脚本在调用COBOL之前被调用(并完成)

我认为您应该像这样编写shell脚本:

#!/bin/bash
funexit ()
{
  echo calling funexit 1>&2
  echo E
}

/caplus/pub/test123<<:EOD:
1
g
$(funexit)Y
:EOD:
!/bin/bash
funexit()
{
回显调用funexit 1>&2
回声E
}
/caplus/pub/test123@ANR

在异常时使用ACCEPT

阿拉

因此,有四行输入的运行看起来像

./sample <fourdatums.txt
one
two
three
four

/sample如果使用terminal而不是heredoc,那么“退出”的等效含义是什么"?@choroba..如果我正确理解了您的意思,那么终端意味着在命令行。如果是这样,那么在命令行,出口将起作用。但我的要求是通过shell脚本通过向COBOL程序传递接受变量来调用COBOL程序。这只能通过heredoc实现。因此我应该使用heredoc。使用exit stateme没有限制nt。任何shell控件中断语句/逻辑都可能用于异常退出进程。@Adaephon。!我尝试了你的建议,但对我无效。它不允许我执行COBOL程序。它只是显示“失败!”发送给终端的消息。我的目的是运行COBOL程序,当运行时向COBOL程序传递的参数不足时,应该退出。这可能是here doc,也可能是任何方法。如果您认为here doc不可能实现这一点,请您建议一个好的解决方案。
!/bin/bash funexit(){a=”$(echo foobar;出口1)“出口1}/caplus/pub/test123@chepner..我尝试了你的建议,但它不符合我的要求。它正在从脚本退出,不允许我执行COBOL程序。你是说你希望在调用
funexit
时退出COBOL程序吗?这是不可能的。
funexit
test123
之前调用过
funexit
ns.如果您想在`test123已经读取前面的输入行之前不调用
funexit
,您必须重写该程序。感谢@chepner的快速响应。您认为有没有任何可能的方法可以通过shell脚本调用COBOL程序?没有;您的COBOL代码本身需要调用
funexit
在适当的时间(或至少在调用时将
funexit
成功或失败作为输入),这样它就可以采取适当的行动。我认为你的想法会起作用。你能不能用一个例子详细说明一下COBOL程序将如何调用
funexit
fuction…我对shell脚本还不熟悉。这可能非常明显。@Brain Tiffin。。我衷心感谢你。但我不想更改COBOL代码。我应该从仅限shell脚本。当从shell脚本向COBOL传递不正确的输入值时,shell脚本应以异常退出条件退出。如果您对此有任何想法,请与我们分享。@ANR;对不起,ANR,但数据永远无法影响代码。永远,永远。缺少数据永远不会影响控制台A接受后,COBOL程序将继续运行代码流。如果您正在编写shell脚本,并且知道您不会提供足够的数据,请不要运行该程序并退出1。如果您不介意突然异常终止,请在向herdoc中提供几行数据后发送一个
kill-9
。同样,您将永远无法“inj”ect是COBOL数据流中的一个出口。但是您可以终止该进程(在heredoc之外,而不是在heredoc中)。
#!/bin/bash
funexit ()
{
    exit 1
}

if ! funexitvalue=$(funexit) ; then
    echo "Failure!"
    exit 1
fi


/caplus/pub/test123<<:EOD:
1
g
$funexitvalue
Y
:EOD:
$ echo "$(echo foobar; exit 1)"
foobar
$ echo $?
0
$ a="$(echo foobar; exit 1)"
$ echo $?
1
$ echo $a
foobar
{ cat << EOF
This text will always be entered to the test123 executable;
EOF
funexit  # exit or return, as needed
cat << EOF
If funexit returned, this will go to test123.
If funexit exited, it will not
EOF
} | caplus/pub/test123
#!/bin/bash
funexit ()
{
  echo calling funexit 1>&2
  echo E
}

/caplus/pub/test123<<:EOD:
1
g
$(funexit)Y
:EOD:
   identification division.
   program-id. sample.

   data division.
   working-storage section.
   01 the-fields.
      05 field-one         pic x(8).
      05 field-two         pic x(8).
      05 field-three       pic x(8).
      05 field-four        pic x(8).

  *> ***************************************************************
   procedure division.

   accept field-one end-accept
   display field-one end-display

   accept field-two end-accept
   display field-two end-display

   accept field-three
       on exception
           display "no field three entered" end-display
       not on exception
          display field-three end-display
   end-accept

   accept field-four
       on exception
           display "no field four entered" end-display
       not on exception
           display field-four end-display
   end-accept

   goback.
   end program sample.
./sample <fourdatums.txt
one
two
three
four
./sample <threedatums.txt
one
two
three
no field four entered