BASH: определить, был ли вызван скрипт из виртуальной машины (Ubuntu) или из приложения W10 bash? - PullRequest
2 голосов
/ 16 января 2020

Есть ли способ для сценария оболочки определить, вызывается ли он из терминала на виртуальной машине, на которой работает Ubuntu, или из терминала W10, использующего вызов bash (установлено приложение Ubuntu в W10)?

Я работаю в обеих средах и у меня есть много полезных сценариев оболочки для повышения эффективности моей работы на виртуальной машине, например, открытие заданных c URL-адресов или выполнение наборов команд. Я бы хотел, чтобы они работали и на стороне Windows. Тем не менее, мои скрипты устанавливают каталоги, которые должны отличаться на моей стороне Windows.

Я установил приложение ubuntu из Windows Store, которое позволяет мне открывать окно 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!

РЕДАКТИРОВАТЬ:

I не может просто проверить действительность каталога по умолчанию, так как сценарии создают каталог, если он не существует. Вместо этого я хочу, чтобы он указывал на другой путь по умолчанию.

Я использую разные имена пользователей, чтобы я мог проверить, что выводом ~ является "Windows или VM user".

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

Таким образом,

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

работает для моего указанного c пользователя. Однако я подозреваю, что хочу использовать это для разных пользователей (например, поделиться им с коллегой). Это требует более надежного пути.

Я не слишком опытен с Linux. Я не знаю, как ориентироваться в мире пользователей, процессов и задач, на которые, я подозреваю, может дать ответ.

Ответы [ 4 ]

1 голос
/ 16 января 2020

Bash предоставляет информацию о системе, в которой она работает, во встроенных переменных MACHTYPE, HOSTTYPE и OSTYPE.

Примерными значениями для физической системы 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
1 голос
/ 16 января 2020

Я давно этим пользуюсь:

if [[ "$(uname -r)" == *Microsoft ]]; then
    do stuff
fi
1 голос
/ 16 января 2020

Вы всегда можете использовать условие if, проверяющее, существует ли путь, и запускать сценарий оттуда:

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

Здесь флаги -f - это условие bash, проверяющее, находится ли файл по указанному пути существует, возвращает true, если это так. Вы можете добавить другие проверки, чтобы проверить, существует ли файл при работе на Windows и еще много чего.

0 голосов
/ 16 января 2020

@ Dexirian и @Michael Hoffman предложили метод, который сработал!


Для меня uname -r возвращает x.x.x-17763-Microsoft из приглашения Windows и 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

работает как шарм!

...