BASH:确定脚本是从虚拟机(Ubuntu)还是W10 bash应用程序调用的?



有没有办法让 shell 脚本确定它是从运行 Ubuntu 的虚拟机中的终端调用的,还是使用bash调用的 W10 终端调用的(在 W10 中安装了 Ubuntu 应用程序(?

我在这两种环境中工作,并且有很多有用的 shell 脚本可以使我在虚拟机上的工作更有效率,例如打开特定的 URL 或运行命令集。我希望他们也在Windows方面工作。但是,我的脚本设置的目录在我的 Windows 端必须有所不同。

我已经从Windows应用商店安装了ubuntu应用程序,它允许我打开一个bash窗口并获取文件。我可以检查~是否返回一个空字符串,但是有没有更强大的方法呢?

我正在运行Windows 10版本17763并使用Ubuntu 18.04 LTS。


例如

C:\.sourceThis.sh

#!/bin/bash
myDir="/home/user/stuff"
cdMySub() {
cd "$myDir/$1"
}

我可以通过以下方式在 Windows 终端中运行它

C:> bash
USER@XXXX:/mnt/c/$ source ./.sourceThis.sh
USER@XXXX:/mnt/c/$ cdMySub someSubDirectoryName
-bash: cd: /home/user/stuff/someSubDirectoryname: No such file or directory
USER@XXXX:/mnt/c/$   #Fail!

但它不起作用,因为 Ubuntu 文件系统与 Windows 不同。

我想将.sourceThis.sh更改为类似

...
if [[ "Something that detects virtual machine" ]] ; then
myDir="/home/user/stuff"
elif [[ "Something that detects 'bash' from Windows prompt" ]] ; then
myDir="/mnt/c/user/stuff"
fi

这样结果反而是

C:> bash
USER@XXXX:/mnt/c/$ source ./.sourceThis.sh
USER@XXXX:/mnt/c/$ cdMySub someSubDirectoryName
USER@XXXX:/mnt/c/stuff/someSubDirectoryName$   #Yeay, success!

编辑:

我不能只检查默认目录的有效性,因为如果目录不存在,脚本会创建该目录。我希望它指向另一个默认路径。

我使用不同的用户名,因此我可以检查~的输出是否为"Windows 或 VM 用户"。

USER@XXXX:/mnt/c$ echo ~
/home/USER

因此

tmpHome=~
if [[ "${tmpHome##*/}" == "USER" ]] ; then
# Windows user
elif [[ "${tmpHome##*/}" == "VM" ]] ; then
# VM user
fi

适用于我的特定用户。但是,我怀疑我想在不同的用户身上使用它(例如,与同事共享(。这需要更强大的方法。

我对Linux不太有经验。我不知道如何浏览用户,流程和任务的世界,我怀疑这可以给出答案。

我已经成功地使用了很长时间:

if [[ "$(uname -r)" == *Microsoft ]]; then
do stuff
fi

您始终可以使用 if 条件检查路径是否存在,并从那里运行脚本:

if [[ -f /home/user/stuff ]]; do 
script if running on linux
else
script if running on windows
fi

这里的 -f 标志是一个 bash 条件,检查指定路径的文件是否存在,如果存在,则返回 true。您可以添加其他验证以检查在Windows等上运行时该文件是否也存在。

Bash 提供了运行它的系统的信息,包括MACHTYPEHOSTTYPEOSTYPE内置变量。

物理 Linux 系统的示例值包括:

MACHTYPE=x86_64-redhat-linux-gnu
HOSTTYPE=x86_64
OSTYPE=linux-gnu

WSL Linux 系统的示例值包括:

MACHTYPE=x86_64-pc-linux-gnu
HOSTTYPE=x86_64
OSTYPE=linux-gnu

检查系统是否为 WSL Linux 的一种可能方法是:

if [[ $MACHTYPE == *-pc-* ]]; then
...
fi

@Dexirian和@Michael霍夫曼提出了一个有效的方法!


对我来说,uname -r从 Windows 提示符返回x.x.x-17763-Microsoft,并在我的虚拟机上x.x.x-xx-generic

因此

if [[ "$(uname -r)" =~ "Microsoft" ]] ; then
myDir="/mnt/c/user/stuff"
elseif [[ "$(uname -r)" =~ "generic" ]] ; then
myDir="/home/user/stuff"
fi

就像一个魅力!

相关内容

最新更新