Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.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
如何控制作业';s";名称“;在Bash?_Bash - Fatal编程技术网

如何控制作业';s";名称“;在Bash?

如何控制作业';s";名称“;在Bash?,bash,Bash,我试图控制我的xterm窗口的标题,我的聪明终于超过了我的知识。:-) 我有三个功能:一个设置窗口标题;接收已传递的命令、调用title函数并执行该命令的函数;以及在使用jobs确定职位后恢复工作的人: title () { echo -en "\e]1;$(hostname) : $1\a\e]2;$(hostname) : $2\a" } run () { title $(basename $1) "$*"; $* } fg () { if [[ "x"

我试图控制我的xterm窗口的标题,我的聪明终于超过了我的知识。:-)

我有三个功能:一个设置窗口标题;接收已传递的命令、调用title函数并执行该命令的函数;以及在使用
jobs
确定职位后恢复工作的人:

title () {
    echo -en "\e]1;$(hostname) : $1\a\e]2;$(hostname) : $2\a"
}

run () {
    title $(basename $1) "$*";
    $*
}

fg () {
    if [[ "x" == "x$1" ]]; then
        title $(jobs | awk '/\['$1'\]/{print $3}') "$(jobs | awk -F '  +' '/\[[0-9]\]\+/{print $3}')";
    else
        title $(jobs | awk '/\['$1'\]/{print $3}') "$(jobs | awk -F '  +' '/\['$1'\]/{print $3}')";
    fi;
    builtin fg $*
}
现在,所有这些都运行得很好…嗯,大部分情况下。通过手动调用函数来设置标题效果很好。通过
run
函数设置标题效果良好。通过恢复作业来设置标题效果良好…除非作业是使用
run
功能启动的:

$ nano foo.txt
<CTRL-Z>
$ run nano bar.txt
<CTRL-Z>
$ jobs
[1]-  Stopped                 nano foo.txt
[2]+  Stopped                 $*
$nano foo.txt
$run nano bar.txt
$jobs
[1] -停止nano foo.txt
[2] +停止$*
好吧,从技术上讲,我想这是
run
函数正在执行的命令的名称,但在本例中,这并不是一件真正有用的事情


因此,由于我不仅已经达到而且远远超出了我对Bash的了解范围,也许这里有人可以帮我解决这个问题。:-)

嗯,这并不理想,但我想出了一个解决方案,至少可以正确设置我的标题:

fg () {
    if [[ "x" == "x$1" ]]; then
        _CMD=$(ps -o cmd --no-headers $(jobs -l | awk '/\[[0-9]\]\+/{print $2}'));
    else
        _CMD=$(ps -o cmd --no-headers $(jobs -l | awk '/\['$1'\]/{print $2}'));
    fi;
    title $(basename $(echo $_CMD | awk '{print $1}')) "$_CMD";
    unset _CMD;
    builtin fg $*;
}
这将使用
jobs
'-l选项获取进程ID,然后使用
ps
查找它,其中列出了正确的命令。不幸的是,
ps
似乎非常慢,在恢复时造成明显的延迟(~¼秒)。man bash说:

fg[jobspec]
在前台恢复jobspec,并使其成为当前作业。 如果jobspec不存在,则shell对当前作业的概念 使用

在“当前工作”中:

符号
%%
%+
引用shell对当前作业的概念,当前作业是最后一个作业 作业在前台停止或在后台启动

这是你真正想做的;模拟fg命令正在执行的操作

这里的大多数其他技巧在参数展开中详细介绍

myfg() { # just so I know what I'm invoking while testing
    local cmdline
    cmdline=$(jobs -l "${1:-%%}") || return # bail if jobs failed
    cmdline=${cmdline:30} # Extract the part we want
    title "${cmdline%% *}" "${cmdline}"

    builtin fg "$jobspec"
}
对于run命令,在许多情况下,eval命令将执行您需要的操作 想要:

但最好用单引号来修饰每个单词,以防止 重新评估它:

eval_safe() {
    local args
    args=( )
    for word in "$@"; do
        word=\'${word//\'/"'\\''"}\'
        args+=( "$word" )
    done
    eval "${args[*]}"
}
引用是bash语法变得非常混乱的地方。我不是在引用
word=${…}
而是在数组中引用它。在替换语法中,您是否被引用很重要。在单个赋值中,bash不进行分词,而在数组中进行分词。(可以执行
“${array[@]//source/target}”
一次完成,但我们要处理多个层次的问题 已经引用了。)

无论如何,这将评估单词并将其传递回bash,如果 他们身上有一些古怪的特征

这就增加了一堆丑陋的引用,而它们可能不是 必要时,让我们添加:

[[ $word =~ ^[a-zA-Z0-9_./]+$ ]] || word=${...}

这表示,“这个词与这个安全正则表达式匹配,或者我们引用它。”这至少是合理的标准正则表达式语法,不同的是,与其他语言不同,您通常不划分正则表达式。

$*
是错误的,但
eval“$@”
也是错误的。正确的方法就是“$@”。也不需要像
eval\u safe()
这样的函数
eval_safe()
还可以双重保护已引用的参数集。否,请尝试以下操作:
foo(){“$@”和};foo sleep 100;jobs-l
你会明白为什么。好的,我明白你的意思。祝您好运,
eval_safe()
快速查看一下,这还不足以用eval引用参数。
[[ $word =~ ^[a-zA-Z0-9_./]+$ ]] || word=${...}