我想使用子shell的魔力和python子进程模块的重定向,但它似乎不起作用,抱怨意外的令牌是括号.例如,命令
cat <(head tmp)
传递给子进程时给出了这个
>>> subprocess.Popen("cat <(head tmp)", shell=True)
<subprocess.Popen object at 0x2b9bfef30350>
>>> /bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `cat <(head tmp)'
Run Code Online (Sandbox Code Playgroud) 所以这个读取是在管道之后执行的,这意味着echo的输出被读入str - 但由于它是在管道之后,因此str的内容现在位于父shell无法读取的子shell中.我的问题是 - str的内容会发生什么?管道是否创建子shell,然后一旦内容被读入str,父进程就会终止子进程并删除str - 或者str的内容是否存在于shell之外的某个地方.就像我们如何看待子壳中的内容一样?我们可以从父shell访问子shell吗?
echo hello | read str
echo $str
Run Code Online (Sandbox Code Playgroud) 我有一个简单的shell脚本,其中包含以下内容:
#!/usr/bin/env bash
set -eu
set -o pipefail
Run Code Online (Sandbox Code Playgroud)
我还具有以下功能:
foo() {
printf "Foo working... "
echo "Failed!"
false # point of interest #1
true # point of interest #2
}
Run Code Online (Sandbox Code Playgroud)
执行foo()作为常规命令按预期工作:脚本退出时#1,由于返回码false是非零和我们使用set -e。
我的目标是将函数的输出捕获到foo()变量中,并仅在执行时出现错误时打印它foo()。这是我想出的:
printf "Doing something that could fail... "
if a="$(foo 2>&1)"; then
echo "Success!"
else
code=$?
echo "Error:"
printf "${a}"
exit $code
fi
Run Code Online (Sandbox Code Playgroud)
该脚本不会在处退出,#1并且会执行"Success!"该if语句的路径。注释掉trueat将#2导致执行语句的"Error:"路径 …
我确定我遗漏了一些简单的东西,但是我正在使用一个执行脚本来调用一些实用程序脚本,我想通过一个管道处理来自实用程序的所有输出.我的问题是实用程序使用stderr报告错误情况,但我无法捕获它以在父脚本中使用.
父脚本:
#!/bin/bash
child 2>&1 >/dev/null
Run Code Online (Sandbox Code Playgroud)
儿童剧本
#!/bin/bash
echo "Print"
echo "Error" 1>&2
Run Code Online (Sandbox Code Playgroud)
我想到的是,stderr中child(以及所有它的命令)将被重定向到stdout(因此没有输出),但是当我执行parent我得到Error回显到终端("打印"发送到/ dev/null的).
我想自动化一项我经常执行的重复任务。这就是为不同的架构创建 rpm。要编译代码并创建 rpm,我需要设置项目环境。设置 env 后,我将为当前架构创建 rpm,并且我应该通过再次设置 env 为其他架构构建 rpm。
我正在尝试使这个过程自动化。问题是一旦设置了 env,我将成为新的 shell,因此我的脚本在子 shell 中不可见。如何自动化这个?
这就是我尝试过的。
cd $project_dir
setenv.sh x86 #creates new sub shell
make clean
make rpm
cp *rpm ~/
exit #exit from the sub shell
setenv.sh x86_64 #creates new shell
make clean
make rpm
cp *.rpm ~/
exit
Run Code Online (Sandbox Code Playgroud)
将 env 设置为 x86 后,接下来的命令不会被执行。
从 BASH 页面:
当使用 source 运行脚本时,它在现有 shell 中运行,脚本创建或修改的任何变量在脚本完成后仍然可用。相反,如果脚本仅作为文件名运行,则将生成一个单独的子 shell(具有一组完全独立的变量)来运行该脚本。
但如果我跑步会发生什么
. myscript &
Run Code Online (Sandbox Code Playgroud)
在这种情况下它作为子 shell 运行吗?. myscript &和 和有什么区别./myscript &?
我写了一个python程序.如果我像这样一个shebang:
#!/usr/bin/python
Run Code Online (Sandbox Code Playgroud)
我用以下文件使文件可执行:
$ chmod 755 program.py
Run Code Online (Sandbox Code Playgroud)
我可以像这样运行程序:
$ ./program.py
Run Code Online (Sandbox Code Playgroud)
这是问题所在.我使用conda虚拟环境.当我运行上面的程序时,系统会创建一个不识别活动环境的子shell:
(my_env) $ ./program.py
ImportError: No module named pymongo
Run Code Online (Sandbox Code Playgroud)
如果我这样做,不过......
(my_env) $ python program.py
# blah blah... runs great
Run Code Online (Sandbox Code Playgroud)
如何在子shell中指定正确的环境?可能吗?我想保存我的手指输入六个字符串的努力python.
另一篇文章,在conda管理环境中的Shebangs,简要介绍了这一点,但没有提供正确的答案.它只是说,而不是激活子shell中的环境,继续忽略shebang ...只需使用$ python program.py语法.
看看这个小脚本:
#!/bin/bash
function do_something() {(
set -e
mkdir "/opt/some_folder" # <== returns 1 -> abort?
echo "mkdir returned $?" # <== sets $0 to 0 again
rsync $( readlink -f "${BASH_SOURCE[0]}" ) /opt/some_folder/ # <== returns 23 -> abort?
echo "rsync returned $?" # <== sets $0 to 0 again
)}
# here every command inside `do_something` will be executed - regardless of errors
echo "run do_something in if-context.."
if ! do_something ; then
echo "running do_something did not work" …Run Code Online (Sandbox Code Playgroud) 我有一个运行mysqld的服务器脚本,并且forks继续运行.举个例子:
./mysqld <parameters> &
echo "Parent runs next line in script."
<do more stuff>
Run Code Online (Sandbox Code Playgroud)
为什么tee等待子进程在结束之前结束?
编辑:
例如,以下内容始终挂起:
./myscript | tee -a logfile.log
Run Code Online (Sandbox Code Playgroud) 我希望能够在子 shell 中设置进程,就好像它不在子 shell 中一样。
$( sleep 3 & )只是忽略 & 符号。
我试过了:
$( sleep 3 & )
$( sleep 3 & ) &
$( sleep 3 ) &
Run Code Online (Sandbox Code Playgroud)
但没有任何改变。
然后我尝试$( disown sleep 3 & )返回
disown:无法操作子 shell 中的作业
这促使我尝试$( set -m; disown sleep 3 & ),但得到了相同的输出。
我什至尝试创建一个可以自行守护的 C++ 程序:
#include <unistd.h>
#include <chrono>
#include <thread>
using namespace std;
int main() {
int ret = fork();
if (ret < 0) return ret; // fork error …Run Code Online (Sandbox Code Playgroud) bash ×10
subshell ×10
shell ×3
python ×2
subprocess ×2
automation ×1
background ×1
c++ ×1
conda ×1
if-statement ×1
linux ×1
pipeline ×1
process ×1
redirect ×1
sh ×1
shebang ×1
stderr ×1
tee ×1