在bash脚本中切换到zsh并执行命令

3
我正在尝试一些虚拟化技术,因此我一直在使用vagrant来提供一个centos7虚拟机,并且现在正在配置应用程序。
我的vagrant配置运行一个bootstrap.sh文件,它是一个bash脚本,在其中我安装了zsh,然后我想按照https://github.com/sorin-ionescu/prezto的步骤进行配置。 第一步是启动zsh然后运行一些命令。
目前这是我所拥有的代码。
echo "Installing zsh"
yum install -y zsh

echo "Configure zsh"
# touch /home/vagrant/.zshrc
exec /usr/bin/zsh
git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
chsh -s /bin/zsh

我希望在我通过ssh连接到虚拟机时,它能成为默认的shell。然而看起来它并没有生效,因为在运行"vagrant up"步骤时没有出现任何错误,所以我想知道这是否可能,并且这样做是否正确? 感谢您!
2个回答

5

exec zsh会用zsh替换您的shell,但不会以任何方式告诉该实例在哪里继续执行,甚至不会运行之前bash调用执行的同一脚本。

一个简单的解决方法是通过heredoc将其余部分的脚本提供给zsh:

/usr/bin/zsh <<'EOF'
git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
chsh -s /bin/zsh
EOF

谢谢!稍微调整了一下,最后成功了。还得以vagrant用户身份执行它。:D - mcbain83
`echo "Installing zsh"
yum install -y zsh
echo "Configure zsh"
sudo -u vagrant zsh <<'EOF'
git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto" setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
EOF chsh -s /bin/zsh vagrant`
- mcbain83

3

exec /usr/bin/zsh 用一个新的 zsh 进程替换正在运行的脚本。此后的代码将不再执行。

你基本上有两种选择:

  1. Put the stuff specific to zsh into a separate script and run that with /usr/bin/zsh:

    vagrant:

    echo "Installing zsh"
    yum install -y zsh
    
    echo "Configure zsh"
    # touch /home/vagrant/.zshrc
    git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
    
    # run external script
    /usr/bin/zsh /home/vagrant/install-prezto.zsh
    
    chsh -s /bin/zsh
    

    /home/vagrant/install-prezto.zsh:

    setopt EXTENDED_GLOB
    for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
      ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
    done
    
  2. Modify the script so that zsh is not needed for the installation:

    echo "Installing zsh"
    yum install -y zsh
    
    echo "Configure zsh"
    # touch /home/vagrant/.zshrc
    git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
    
    # use find instead of *zsh* to link files
    find "${ZDOTDIR:-$HOME}/.zprezto/runcoms/" -maxdepth 1 -type f -! -name README.md --exec ln -s {} "${ZDOTDIR:-$HOME}/" +
    
    chsh -s /bin/zsh
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接