Bash:在调用shell的上下文中执行脚本

y0u0uwnf  于 2023-05-07  发布在  Shell
关注(0)|答案(2)|浏览(191)

我的理解是,当我使用$ ./myscript.sh这样的语法在BASH shell中执行脚本时,会启动一个子shell,代码在该shell中运行,STDOUT和STDERR输出被打印在我的shell上,STDIN是从我的shell中获取的。这就是脚本交互的方式。
文件“myscript”的第一行是#!/bin/bash,这说明了用于执行脚本文件中语法的解释器。
如果我使用语法source myscript.sh,脚本中的代码将被“拉”到当前环境中并在那里执行,而不是在子shell中执行。我不能让下面的代码在我用$ ./myscript.sh调用的脚本中运行,并影响我当前的shell:

#!/bin/bash

PS1='`
  if [ $? -eq 0 ];
    then echo -n "\[\033[00;35m\]\u\[\033[01;32m\]@\[\033[00;35m\]\h\[\033[00;32m\](\[\033[01;35m\]\W\[\033[01;32m\])\[\033[00;32m\]\$";
    else echo -n "\[\033[00;35m\]\u\[\033[01;31m\]@\[\033[00;35m\]\h\[\033[01;31m\](\[\033[35m\]\W\[\033[31m\])\[\033[00;31m\]\$";
  fi`\[\033[0m\]'

如果我删除#!/bin/bash并使用source,此脚本将更改我的命令提示符。是否可以将它安排在脚本中,使我可以用$ ./myscript.sh调用它,并且它将更改我当前的shell,而不是子shell?

2fjabf4q

2fjabf4q1#

一旦你调用了一个没有source的脚本,它就运行在一个子shell中,没有办法改变父shell的环境。
您可以使用shebang行来源化脚本。它只是在源代码时被忽略。

q5lcpyga

q5lcpyga2#

我不太确定你想做什么,所以我不认为我能解决你的问题(我不知道$?是如何设置的)。也就是说,我今天刚刚发现的可能会帮助有类似问题的人。
OP的脚本无法实现其目的,因为它试图应用的更改在子shell退出时丢失。我以前已经为此挣扎过好几次了,今天又和它搏斗了。我想出了一个不同的方法,重写脚本以 * 生成 * 但 * 不应用 * 参数。
为了解决OP的困难,创建以下脚本,它遵循OP脚本的精神(我随意使用了提示字符串和条件语句):

#!/usr/bin/env bash                                                             
# file: setps1
                                                                                
if [ "$1" -eq 0 ]; then                                                         
    echo -n $'\e[35;1m\\u\e[m@\e[32;1m\\h\e[m(\e[32;1m\\W\e[m)\$ '              
else                                                                            
    echo -n $'\e[35;1m\\u\e[m@\e[31;1m\\h\e[m(\e[31;1m\\W\e[m)\$ '              
fi

然后调用它:

PS1=$( ./setps1 1 )

请注意,这也适用于需要多个参数的命令。在我的例子中,脚本最初使用三个计算参数调用enable,它以熟悉的方式失败了。我重写了该脚本,以便只输出三个计算参数,并将该脚本安装在/usr/local/bin中,以方便访问。使用该脚本为enable提供参数,而不必提供复杂的路径,这使得使用我的内建更加用户友好。

相关问题