Smartskaft2
Smartskaft2

Reputation: 510

BASH: Determine if script was called from virtual machine (Ubuntu), or the W10 bash app?

Is there a way for a shell script to determine if it is called from a terminal in a virtual machine running Ubuntu, or a W10 terminal using the bash call (installed Ubuntu app in W10)?

I am working in both environments and have a lot of useful shell scripts to make my work more efficient on the virtual machine, e.g. opening specific URLs or running sets of commands. I would like them to work on the Windows side as well. However, my scripts sets up directories which will have to be different on my Windows side.

I have installed the ubuntu app from Windows Store, which allows me to open a bash window and source the files. I could just check if ~ returns an empty string, but is there a more robust way of doing it?

I am running Windows 10, version 17763 and using Ubuntu 18.04 LTS.


E.g.

C:\.sourceThis.sh

#!/bin/bash

myDir="/home/user/stuff"

cdMySub() {
    cd "$myDir/$1"
}

I can run this in a Windows terminal by

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!

but it does not work, since the Ubuntu file system is different to Windows.

I would like to change .sourceThis.sh to something like

...
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

so that the outcome is instead

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

EDIT:

I cannot just check for the validity of the default directory, since the scripts create the directory if it does not exist. I want it to point to another default path instead.

I use different user names, so I could check that the output from ~ is the "Windows or VM user".

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

Thus,

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

works for my specific user. However, I suspect that I want to use this on different users (e.g. share it with a colleague). This demands a more robust way.

I am not too experience with Linux. I do not know how to navigate the world of users, processes and tasks, which I suspect can give the answer.

Upvotes: 2

Views: 625

Answers (4)

pjh
pjh

Reputation: 8184

Bash provides information about the system that is running it it the MACHTYPE, HOSTTYPE, and OSTYPE built-in variables.

Example values for a physical Linux system are:

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

Example values for a WSL Linux system are:

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

One possible way to check if the system is WSL Linux is:

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

Upvotes: 1

Smartskaft2
Smartskaft2

Reputation: 510

@Dexirian and @Michael Hoffman suggested a method that worked!


For me uname -r returns x.x.x-17763-Microsoft from the Windows prompt and x.x.x-xx-generic on my virtual machine.

Thus,

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

works like a charm!

Upvotes: 0

Michael Hoffman
Michael Hoffman

Reputation: 34364

I have used this for a long time successfully:

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

Upvotes: 1

Dexirian
Dexirian

Reputation: 575

You could always use an if condition checking whether the path exists, and run the script from there :

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

Here the -f flags is a bash condition checking whether the file at specified path exists, returns true if it does. You can add other validations to check whether the file also exists when running on Windows and whatnot.

Upvotes: 1

Related Questions