Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 使用set-x、capture-pid和all-output时重定向bash脚本中的所有输出_Linux_Bash_Shell_Unix - Fatal编程技术网

Linux 使用set-x、capture-pid和all-output时重定向bash脚本中的所有输出

Linux 使用set-x、capture-pid和all-output时重定向bash脚本中的所有输出,linux,bash,shell,unix,Linux,Bash,Shell,Unix,我正在修改一个旧脚本,出于某种原因,它使用了子shell。我不确定是不是潜艇把我绊倒了。我真正想要的是启动一个服务,并将所有STDOUT和STDERR捕获到一个文件及其PID。此外,我希望在日志文件中包含一些调试信息。考虑下面的脚本(StestFoo.SH): 这似乎很有效,因为我正在捕获日志和PID的大部分输出,但由于某些原因,并不是所有的输出都被重定向。当我运行脚本时,我在终端中看到: [me@home ~]$ sudo startFoo.sh Some output [me@home ~]

我正在修改一个旧脚本,出于某种原因,它使用了子shell。我不确定是不是潜艇把我绊倒了。我真正想要的是启动一个服务,并将所有STDOUT和STDERR捕获到一个文件及其PID。此外,我希望在日志文件中包含一些调试信息。考虑下面的脚本(StestFoo.SH):

这似乎很有效,因为我正在捕获日志和PID的大部分输出,但由于某些原因,并不是所有的输出都被重定向。当我运行脚本时,我在终端中看到:

[me@home ~]$ sudo startFoo.sh
Some output
[me@home ~]$ + foo -argument1=bar -argument2=value
如何在显示
[me@home~]$+foo…

注意,这个问题可能与另一个问题有关:,但是我的具体用法不同

更新:我的脚本现在看起来像这样,但有些地方仍然不太正确:

#!/bin/bash
VARIABLE=$(something_dynamic)
echo "Some output"
(
   # Enable debugging
   set -x
   foo -argument1=bar \
      -argument2=$VARIABLE

   # Disable debugging
   set +x

) > /tmp/foo_service.log 2>&1 &
PID=$!
echo $PID > foo.pid
#!/bin/bash 
VARIABLE=$(something_dynamic) 
echo "Some output" 
{ 
   # Enable debugging 
   set -x 
   foo -argument1=bar \ 
      -argument2="$VARIABLE" &
   PID=$! 
   echo $PID > foo.pid 

   # Disable debugging 
   set +x
} > /tmp/foo_service.log 2>&1
但是,当我这样做时,PID文件包含
startFoo.sh
的PID,而不是
foo
的实际调用,这正是我真正想要捕获并能够杀死的。理想情况下,我可以用一个PID同时杀死
startFoo.sh
foo
,但我不知道怎么做。这通常是如何处理的

更新:解决方案(感谢与@konsolebox的对话)如下:

#!/bin/bash
VARIABLE=$(something_dynamic)
echo "Some output"
(
   # Enable debugging
   set -x
   foo -argument1=bar \
      -argument2=$VARIABLE

   # Disable debugging
   set +x

) > /tmp/foo_service.log 2>&1 &
PID=$!
echo $PID > foo.pid
#!/bin/bash 
VARIABLE=$(something_dynamic) 
echo "Some output" 
{ 
   # Enable debugging 
   set -x 
   foo -argument1=bar \ 
      -argument2="$VARIABLE" &
   PID=$! 
   echo $PID > foo.pid 

   # Disable debugging 
   set +x
} > /tmp/foo_service.log 2>&1

2>&1>/tmp/foo_service.log
更改为
/tmp/foo_service.log 2>&1


您应该首先将FD1重定向到该文件,然后让FD2复制它。您在前者上所做的是,首先将fd 2重定向到1,它只复制默认的标准输出,而不复制在它之后打开的文件的fd。

2>&1>
更改为
&>
,看看它是否工作。谢谢@konsolebox,我认为它工作正常,但我不能完全确定我是否理解解决方案。你是说这里发生了两个不同的重定向吗?“让FD2复制它”是什么意思。是否要复制指令以重定向输出?@b.long是有两个单独的重定向发生。基本上,您只需操纵文件描述符,就可以同时处理相同的流或相同的文件。解释起来并不容易,但你可以考虑更多地阅读它。维基百科可能也会提供一些。有趣,好的。在进一步的测试中,我最终修改了脚本。也许我解决这个问题的直觉是错误的。由于
foo
是长时间运行的,我认为它需要后台处理,以便
startFoo.sh
将用户返回到命令提示符,但现在我似乎捕获了错误的PID。我已经更新了我的问题。@b.long您在set-x/set+x前后运行的唯一命令是foo吗?foo是脚本还是二进制?是的,
foo
是在
set-x
set+x
之间运行的唯一命令,但我确实有一个条件before
set-x
和一些额外的输出,我想将其定向到
/tmp/foo\u服务中。log