请问为什么下面的linux命令不能生效?

@Ta 2022-08-16发布,2022-08-16修改 38516点击

需求场景:

通过编程方式启动一个子进程,临时更改用户python命令的指向。
所以我想到了别名方式。想临时覆盖用户原有的python命令

实际思路:

  1. 一条命令完成设置别名,并且使用别名命令【失败】
$ alias python=python2;python --version

显示python ,找不到该命令。
不关闭shell,下一行输入lll ,别名是可以生效的。
但是 并不能做到我一条命令临时覆盖lll的命令。

  1. 多条命令设置别名以及使用别名命令【失败】
    执行完alias python=python2以后 流就关闭了,我无法再write输入流,让其模拟输入下一条命令的操作

请教大佬有没有其他解决方案

回复列表(21|隐藏机器人聊天)
  • @Ta / 2022-08-16 / /

    Bash 手册里,Alias 条目说:

    Bash always reads at least one complete line of input, and all lines that make up a compound command, before executing any of the commands on that line or the compound command. Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read. The commands following the alias definition on that line are not affected by the new alias.

    大意:

    Bash 总是至少读取完整的一行(或多行,保证复合命令也读完整咯),接着立即扩展别名,最后再执行命令

    另外,你的ls -ll需要用引号括起来,否则-ll不是lll的一部分,而是成为alias的参数。如:

    $ alias lll='ls -ll'
    
  • @Ta / 2022-08-16 / /
    并不行哦
    ubuntu@ubuntu:~$ alias lll='ls-ll';lll

    Command 'lll' not found, did you mean:

      command 'llc' from deb llvm
      command 'dll' from deb brickos
      command 'llt' from deb storebackup
      command 'lli' from deb llvm-runtime

    Try: sudo apt install <deb name>
  • @Ta / 2022-08-16 / /

    @弟妹,看来你是没看懂大意,也没看英文原文呐。。

  • @Ta / 2022-08-16 / /
    @无名啊,抱歉 我不是用我举得例子测试的。我现在明白了,不加引号,是参数没有携带。并且会提示alias 没有ll参数
    现在明白你引用的大意了,所以我补充了我的需求场景,明白alias不符合我的要求了
  • @Ta / 2022-08-16 / /

    @弟妹

    1. Bash 总是至少读取完整的一行

      读取alias lll='ls -ll';lll

    2. 接着立即扩展别名

      alias不是别名,lll也不是别名(你的alias lll='ls-ll'此时还未执行),所以不用扩展

    3. 最后再执行命令

      1. 执行alias lll='ls -ll'
      2. 执行lll
  • @Ta / 2022-08-16 / /
    @无名啊,是的 因为我是子进程打开的shell 我无法做到输入两条命令,因为我不是在tty下进行输入的
  • @Ta / 2022-08-16 / /

    @弟妹

    Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt.

    需要在交互式模式,或者启用expand_aliasesalias才能生效

  • @Ta / 2022-08-16 / /

    @弟妹

    多条命令设置别名以及使用别名命令【失败】

    贴下代码?

  • @Ta / 2022-08-16 / /

    @无名啊,以Node.js 创建子进程为例

    import * as child from 'child_process'
    
    export async function execRequest(cmd: string, commands: string[]) {
        return new Promise((resolve) => {
            let spawnChild = child.spawn(cmd)
            spawnChild.stdout.on('data', ch => {
                console.log(ch.toString().trim())
            })
            spawnChild.stderr.on('data', ch => {
                console.log(ch.toString().trim())
            })
    
            spawnChild.on('exit', code => {
                console.log(code)
            })
    
            commands.forEach((command) => {
                spawnChild.stdin.write(`${command}\n`)
            })
    
            spawnChild.stdin.end('\nexit\n')
        })
    }
    
    await execRequest('bash',['alias python233=python2','python233 --version 2>&1'])
    

    以上代码 大概意思是,输入bash,并开启交互式shell

    第一次流写入alias python233=python2 并且回车
    第二次流写入python233 --version 2>&1 并且回车
    输出流提示
    提示python233不存在
    PS: python --version竟然输出到错误流 真离谱

  • @Ta / 2022-08-16 / /

    @弟妹,看来,你没看 7 楼

    await execRequest('bash',['shopt -s expand_aliases', 'alias python233=python2', 'python233 --version 2>&1'])
    
  • @Ta / 2022-08-16 / /

    @弟妹

    PS: python --version竟然输出到错误流 真离谱

    我瞅了瞅,应该是输出至stdout的?

    $ python3 --version | sed 's/^/[STDOUT] /'
    [STDOUT] Python 3.10.5
    
  • @Ta / 2022-08-16 / /
    @无名啊,我知道7楼这个方案,因为机器没网,电脑里没有这个软件。所以就没采用这个。。。

    使用的交互式shell,是不好用的。

    然后,我是拿python2.7测试--version输出到错误流的(我还没测试其他机器的2.7是否也这样)
  • @Ta / 2022-08-16 / /

    @弟妹

    噢,我看漏了这一句

    并开启交互式shell

    看来,你读了 7 楼的

    只是,这nodejs代码里,哪一行是代表连接到了tty吗?(我不熟悉nodejs,但我还是能看得懂很多js的,即使是到ES2022

  • @Ta / 2022-08-16 / /

    @弟妹

    因为机器没网,电脑里没有这个软件。所以就没采用这个。。。

    Emm..?不需要额外安装啥软件呀,只是加一行bash代码

    然后,我是拿python2.7测试--version输出到错误流的(我还没测试其他机器的2.7是否也这样)

    我不熟悉Python 2,我电脑也没装,那就不清楚了

  • @Ta / 2022-08-16 / /
    @无名啊,我是python2 2>file.err 这么测试的,sed我是不太会用
  • @Ta / 2022-08-16 / /
    @无名啊,shopt 这个软件我电脑没有。。


    22:50 测试发现,原来是我用的zsh没有。我没具体看这个报错,我明天再试试

    shopt is not a command, but a shell built-in. bash knows what to do with it because it's a bash built-in , but zsh has no idea what it is. You'll want to look into setopt which is a zsh built-in, and put those values into a new .zshrc script.
  • @Ta / 2022-08-16 / /

    @弟妹,我觉得,你的nodejs应该只是提供了普通stdin,加上你又没用bash -i参数,所以启动的bash应该不是交互式的

    这时你用 10 楼的代码,alias应该就能生效了

  • @Ta / 2022-08-16 / /

    @弟妹,你用的zsh啊。。这个我不熟悉,你需要@老虎会游泳

  • @Ta / 2022-08-16 / /

    @弟妹shoptbash的内置命令,不需要额外安装

    而且你在nodejs里启动的也是bash,应该没问题?

    $ type shopt
    shopt is a shell builtin
    
添加新回复
回复需要登录