如何从后台运行功能打印输出后返回bash提示符? [英] How to return to bash prompt after printing output from backgrounded function?

查看:212
本文介绍了如何从后台运行功能打印输出后返回bash提示符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何能回到我的bash提示符从被放在后台功能进行打印输出后?

How can I return to my bash prompt automatically after printing output from a function that was put in the background?

例如,当我在bash shell中运行以下脚本:

For example, when I run the following script in a bash shell:


fn(){
        sleep 10
        echo "Done"
        exit
}
fn &

脚本运行之后,它立即返回我的提示。 10秒后,它打印完成,然后在新行显示一个闪烁的光标:

After running the script, it immediately returns my prompt. After 10 seconds, it prints "Done" and then displays a blinking cursor on a new line:


$ Done
▏

该脚本不再运行,但我没有得到我的提示回去,直到我preSS <大骨节病>返回

有没有办法强制返回bash提示符打印后,完成?

Is there any way to force a return to the bash prompt after printing "Done"?

一个相关的问题是:<一href=\"http://stackoverflow.com/questions/13227530/is-there-a-way-for-a-backgrounded-task-to-inform-the-terminal-to-print-a-new-pro\">Is有一个后台运行的任务通知终端来打印新的提示?的但是从某种意义上说,这个问题询问一个后台运行的程序。答案提供有适用于程序的发送到该背景,但似乎不为一的功能工作的被发送到的背景(如在实施例我提供)。

A related question is: Is there a way for a backgrounded task to inform the terminal to print a new prompt? However, that question asks about a backgrounded program. The answer supplied there applies to a program that is sent to the background, but doesn't seem to work for a function that is sent to the background (as in the example I supplied).

要澄清:我要找(,例如为 myscript.sh ),以挽救整个code片段上方,然后运行它作为一个前景脚本(如,如庆典myscript.sh )。

To clarify: I am looking to save the entire code snippet above (e.g., as myscript.sh) and then run it as a foreground script (e.g., as bash myscript.sh).

修改:以上当然只是一个MWE的。这个问题的背景下是:

EDIT: The above is of course just a MWE. The context of this problem is:


  1. 用户运行脚本

  2. 脚本提交PBS作业,启动尾矿在后台输出文件,并要求 FN和放大器;

  3. 用户得到提示回来了,可以开始做其他的事情。

  4. 当作业开始运行出现用户的终端上作业输出

  5. FN 监视队列并杀死
  6. 在当前作业完成
  7. 用户抱怨没有得到及时回(即不必preSS <大骨节病>输入)这个结束后。

  1. User runs script
  2. Script submits PBS job, starts tailing the output file in the background, and calls fn &
  3. User gets prompt back, may start doing other things.
  4. Job output appears on user's terminal when job starts running
  5. fn monitors the queue and kills tail when the job finishes.
  6. Users complain about not getting prompt back (i.e., having to press Enter) after this finishes.

下面是一些不太最低code:

Here's some less minimal code:


watch_queue(){
    until [  `qstat | grep $job | wc -l` -lt 1 ]; do
        sleep 2
    done
    kill -9 $pid
    tput setaf 7
    tput setab 0
    echo "Hit ENTER to return to your command prompt."
    tput sgr0
    exit 0
}

cmd="something complicated that is built at runtime"
outfile="ditto"
queue="selected at runtime, too"

job=`echo "cd \$PBS_O_WORKDIR  && $cmd >> $outfile " | 
     qsub -q $queue -e /dev/null -o /dev/null | 
     awk 'BEGIN { FS="." } { print $1 }'`

echo "Job $job queued on $queue: $cmd"
eval "tail -f -F $outfile 2>/dev/null &"
pid=$!
watch_queue &

当然,这将是对我来说更容易很多,如果我的用户可以只由一个单独的文件拿起作业输出,或操纵前景和背景之间的工作靠自己,但他们不能。他们甚至不能按照脚本中的说明打<大骨节病>输入拿到看的提示回来......我不能打开另一个窗口 - 他们没有一个显示服务器。

Of course it would be a lot easier for me if my users could just pick up the job output from a separate file, or manipulate jobs between foreground and background on their own, but they can't. They can't even follow the instructions in the script to hit Enter to get the "look" of a prompt back... And I can't open another "window" - they do not have a display server.

推荐答案

编译低于code到文件的a.out

Compile below code to file a.out

#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    /* char buf[] = "date\n"; */
    char buf[] = "\n";  /* Data to write on terminal */
    int i;
    int fd = open(argv[1], O_WRONLY);  /* Open terminal */

    /* printf("fd = %d\n", fd); */
    for (i = 0; i < sizeof buf - 1; i++)  /* Write data */
      ioctl(fd, TIOCSTI, &buf[i]);
    close(fd);  /* Close file descriptor */
    return 0;
}

这个程序需要作为命令行参数的路径。
程序将打开的路径和编写新的行这条道路。

This program expects a path as command line argument. Program will open the path and write a new line to this path.

如果这条道路会包含一个可写的终端运行bash脚本的文件描述符,这会导致庆典赶上新的提示。

If this path happen to contain the file descriptor of a writable terminal running bash script, this would cause bash to catch a new prompt.

修改您的shell脚本

Modify your shell script

fn(){
        sleep 10
        echo "Done"
        ./a.out /proc/$PPID/fd/0
}
fn &

该脚本将做一些工作(这里再与睡眠psented $ P $),然后用参数作为母公司的输入端子pviously调用程序的书面$ P $。父终端将获得新的生产线,赶上新的提示此提示如果有丢弃的流浪命令。

This script would do some job (represented with sleep here) and then call the utility written previously with argument as input terminal of parent. Parent terminal would receive a new line and catch a new prompt discarding the stray command on this prompt if any.

的/ proc 包含所有进程目录。文件夹的名称匹配进程的PID。
Inbuild变量 PPID 包含父进程的PID。
PID 目录中,存在包含开放式流的 FD 目录。
0 是输入, 1 是输出和 2 对于错误。有可能是取决于过程更加开放流。我们感兴趣的是 0 流在这里。

/proc contains directories for all processes. Name of folder matches to the pid of process. Inbuild variable PPID contains the parent's pid. Inside the pid directory, there is an fd directory containing open streams. 0 is for input, 1 is for output and 2 is for error. There may be more open streams depending on the process. We are interested in 0 stream here.

这篇关于如何从后台运行功能打印输出后返回bash提示符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆