3

我想以screen分离状态启动会话,以便它们在脚本完成后终止这样我就可以编写一个脚本来执行多个screen会话,而不必手动一个接一个地启动每个会话,然后分离,然后再继续到下一个屏幕会话。

此脚本取决于设置的某些环境变量。screen通常,当我在常规shell 中运行此脚本时bash,我只需在我的.bash_profile文件中设置这些环境变量。

此外,当我以非分离状态启动屏幕并放入我的.screenrc文件时:

shell -$SHELL

那么我也没有问题。

问题仅在我执行时出现,screen -dm然后我的脚本无法运行,因为我需要的环境没有设置。

我如何告诉屏幕.screenrc在以分离状态启动时引用该文件,以便它最终.bash_profile在启动时获取我的资源?

更新

当我执行时screen -dmL env,我可以看到我的一些但不是所有的环境变量都存在。

4

2 回答 2

3

我相信您的问题是,在screen以分离模式启动时,screen不会启动登录 shell 或交互式 shell,因此您的不是来源(有关启动时来源文件的说明,.bash_profile请参阅的“INVOCATION”部分) man bash. 请注意,-您的前导

shell -$SHELL

设置意味着 shell 将始终作为登录 shell 启动,因此.bash_profile将被获取。

您的问题的一些可能的解决方案:

  1. 不要screen以分离状态开始。请注意screen,如果脚本作为命令给出,则在以通常方式启动时脚本完成时终止。例如,对于脚本test.sh

    #!/bin/bash
    
    for n in `seq 1 5`; do
      echo $n
      sleep 1
    done
    

    运行screen ./test.sh脚本并在 5 秒后终止。

  2. .bash_profile在屏幕中运行的脚本中手动获取您的源代码。即添加

    source ~/.bash_profile
    

    到脚本的开头,MyScript.

更新 1

我仍然怀疑问题是你.bash_profile的没有被加载,所以让我们确保你.screenrc 被加载。尝试添加

screen touch /tmp/when-was-screen-rc-sourced

到你的最后,~/.screenrc然后做

screen MyScript

接着

ls -lt --full-time /tmp

尝试几种不同的方式启动屏幕,看看是否~/.screenrc真的无法加载。

同样,您可以添加一行

touch /tmp/when-was-bash-profile-sourced

到你的最后,~/.bash_profile看看什么时候加载。

更新 2

这是一个示例,显示screen当您有该行时确实运行您的脚本

screen touch /tmp/when-was-screen-rc-sourced

在你的末尾~/.screenrc

这是测试文件test.sh

#!/bin/bash

touch /tmp/when-did-test-sh-start
for n in `seq 1 5`; do
  echo $n
  sleep 1
done
touch /tmp/when-did-test-sh-finish

这是证据。跑步

$ touch /tmp/when-did-we-start; screen -d -m ./test.sh; sleep 6; ls -ltr --full-time /tmp | tail -n4

给出输出

-rw------- 1 collins collins    0 2013-11-06 14:43:03.643564802 -0800 when-did-we-start
-rw------- 1 collins collins    0 2013-11-06 14:43:03.659565385 -0800 when-was-screen-rc-sourced
-rw------- 1 collins collins    0 2013-11-06 14:43:03.671565892 -0800 when-did-test-sh-start
-rw------- 1 collins collins    0 2013-11-06 14:43:08.707770194 -0800 when-did-test-sh-finish

所以,我仍然认为问题与您的~/.bash_profile(或任何定义您丢失的环境变量的定义)未加载有关。

更新 3

在这一点上,可能更容易准确地理解你想要完成的事情,然后想出一个更好的方法来完成它。要做到这一点,提供一个最小的示例脚本来说明您的问题对您很有帮助(即,当您直接运行它时它可以工作,或者在启动屏幕后手动运行,但在通过screen ./example.shor直接运行时不起作用screen -d -m ./example.sh)。

但是,与此同时,这是另一个潜在的解决方法(您是否尝试过我上面的第二个原始建议, ~/.bash_profile直接在您的脚本中采购您的?):

使用 bash 运行您的脚本,明确地使 bash 交互和/或登录 shell。例如,对于交互式登录 shell

screen -d -m bash -i -I ./MyScript

有关bash 在什么模式下加载的文件的一个很好的总结,请参见 此处。根据man bash,该bash -i -I组合应该使 bash 在交互式登录模式下运行您的脚本,因此~/.bash_profile应该得到来源。

于 2013-11-05T22:00:48.420 回答
2

不需要 ~/.screenrc
让你的 ~/.bash_profile 一行:source ~/.bashrc
把你的别名和环境变量放在 ~/.bashrc

在 ~/.bashrc 中,编写如下代码:

alias myalias="echo ThisWorks"

run_myalias_in_bg_screen (){
    screen -dmS mytestscreen bash -c 'exec bash'
    screen -r mytestscreen -p0 -X stuff "myalias"
    screen -r mytestscreen -p0 -X eval "stuff \015"
}

现在在您的终端中测试它

$ run_myalias_in_bg_screen
$ screen -r mytestscreen
于 2016-11-17T20:44:54.283 回答