提交 dce22cf7 编写于 作者: R Rob Lourens

Fall back on node API when $SHELL is not set, for

user shell and shell environment discovery
See github/codespaces#1639
上级 96b426ef
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as os from 'os';
import * as platform from 'vs/base/common/platform';
import * as processes from 'vs/base/node/processes';
/**
* Gets the detected default shell for the _system_, not to be confused with VS Code's _default_
* shell that the terminal uses by default.
* @param p The platform to detect the shell of.
*/
export function getSystemShell(p: platform.Platform, environment: platform.IProcessEnvironment = process.env as platform.IProcessEnvironment): string {
if (p === platform.Platform.Windows) {
if (platform.isWindows) {
return getSystemShellWindows(environment);
}
// Don't detect Windows shell when not on Windows
return processes.getWindowsShell(environment);
}
// Only use $SHELL for the current OS
if (platform.isLinux && p === platform.Platform.Mac || platform.isMacintosh && p === platform.Platform.Linux) {
return '/bin/bash';
}
return getSystemShellUnixLike(environment);
}
let _TERMINAL_DEFAULT_SHELL_UNIX_LIKE: string | null = null;
function getSystemShellUnixLike(environment: platform.IProcessEnvironment): string {
if (!_TERMINAL_DEFAULT_SHELL_UNIX_LIKE) {
let unixLikeTerminal: string;
if (platform.isWindows) {
unixLikeTerminal = '/bin/bash'; // for WSL
} else {
unixLikeTerminal = environment.SHELL;
if (!unixLikeTerminal) {
try {
// It's possible for $SHELL to be unset, this API reads /etc/passwd. See https://github.com/github/codespaces/issues/1639
// Node docs: "Throws a SystemError if a user has no username or homedir."
unixLikeTerminal = os.userInfo().shell;
} catch (err) { }
}
if (!unixLikeTerminal) {
unixLikeTerminal = 'sh';
}
// Some systems have $SHELL set to /bin/false which breaks the terminal
if (unixLikeTerminal === '/bin/false') {
unixLikeTerminal = '/bin/bash';
}
}
_TERMINAL_DEFAULT_SHELL_UNIX_LIKE = unixLikeTerminal;
}
return _TERMINAL_DEFAULT_SHELL_UNIX_LIKE;
}
let _TERMINAL_DEFAULT_SHELL_WINDOWS: string | null = null;
function getSystemShellWindows(environment: platform.IProcessEnvironment): string {
if (!_TERMINAL_DEFAULT_SHELL_WINDOWS) {
const isAtLeastWindows10 = platform.isWindows && parseFloat(os.release()) >= 10;
const is32ProcessOn64Windows = environment.hasOwnProperty('PROCESSOR_ARCHITEW6432');
const powerShellPath = `${environment.windir}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}\\WindowsPowerShell\\v1.0\\powershell.exe`;
_TERMINAL_DEFAULT_SHELL_WINDOWS = isAtLeastWindows10 ? powerShellPath : processes.getWindowsShell(environment);
}
return _TERMINAL_DEFAULT_SHELL_WINDOWS;
}
......@@ -5,11 +5,12 @@
import { spawn } from 'child_process';
import { generateUuid } from 'vs/base/common/uuid';
import { isWindows } from 'vs/base/common/platform';
import { isWindows, platform } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { getSystemShell } from 'vs/base/node/shell';
/**
* We need to get the environment from a user's shell.
......@@ -78,7 +79,8 @@ async function doResolveUnixShellEnv(logService: ILogService): Promise<typeof pr
logService.trace('getUnixShellEnvironment#env', env);
logService.trace('getUnixShellEnvironment#spawn', command);
const child = spawn(process.env.SHELL!, ['-ilc', command], {
const systemShellUnix = getSystemShell(platform);
const child = spawn(systemShellUnix, ['-ilc', command], {
detached: true,
stdio: ['ignore', 'pipe', process.stderr],
env
......
......@@ -17,13 +17,14 @@ import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/ext
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { ExtHostVariableResolverService } from 'vs/workbench/api/common/extHostDebugService';
import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal';
import { detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal';
import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
import { BaseExtHostTerminalService, ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { withNullAsUndefined } from 'vs/base/common/types';
import { getSystemShell } from 'vs/base/node/shell';
export class ExtHostTerminalService extends BaseExtHostTerminalService {
......
......@@ -7,12 +7,12 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstanceService';
import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal';
import { TerminalNativeContribution } from 'vs/workbench/contrib/terminal/electron-browser/terminalNativeContribution';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
import { getTerminalShellConfiguration } from 'vs/workbench/contrib/terminal/common/terminalConfiguration';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { getSystemShell } from 'vs/base/node/shell';
// This file contains additional desktop-only contributions on top of those in browser/
......
......@@ -9,7 +9,6 @@ import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/electron-brows
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IProcessEnvironment, platform, Platform } from 'vs/base/common/platform';
import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess';
import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal';
import type { Terminal as XTermTerminal } from 'xterm';
import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
import type { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11';
......@@ -22,6 +21,7 @@ import { IConfigurationResolverService } from 'vs/workbench/services/configurati
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ILogService } from 'vs/platform/log/common/log';
import { getSystemShell } from 'vs/base/node/shell';
let Terminal: typeof XTermTerminal;
let SearchAddon: typeof XTermSearchAddon;
......
......@@ -5,62 +5,11 @@
import * as os from 'os';
import * as platform from 'vs/base/common/platform';
import * as processes from 'vs/base/node/processes';
import { readFile, fileExists, stat } from 'vs/base/node/pfs';
import { LinuxDistro, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal';
import { coalesce } from 'vs/base/common/arrays';
import { normalize, basename } from 'vs/base/common/path';
/**
* Gets the detected default shell for the _system_, not to be confused with VS Code's _default_
* shell that the terminal uses by default.
* @param p The platform to detect the shell of.
*/
export function getSystemShell(p: platform.Platform, environment: platform.IProcessEnvironment = process.env as platform.IProcessEnvironment): string {
if (p === platform.Platform.Windows) {
if (platform.isWindows) {
return getSystemShellWindows(environment);
}
// Don't detect Windows shell when not on Windows
return processes.getWindowsShell(environment);
}
// Only use $SHELL for the current OS
if (platform.isLinux && p === platform.Platform.Mac || platform.isMacintosh && p === platform.Platform.Linux) {
return '/bin/bash';
}
return getSystemShellUnixLike(environment);
}
let _TERMINAL_DEFAULT_SHELL_UNIX_LIKE: string | null = null;
function getSystemShellUnixLike(environment: platform.IProcessEnvironment): string {
if (!_TERMINAL_DEFAULT_SHELL_UNIX_LIKE) {
let unixLikeTerminal = 'sh';
if (!platform.isWindows && environment.SHELL) {
unixLikeTerminal = environment.SHELL;
// Some systems have $SHELL set to /bin/false which breaks the terminal
if (unixLikeTerminal === '/bin/false') {
unixLikeTerminal = '/bin/bash';
}
}
if (platform.isWindows) {
unixLikeTerminal = '/bin/bash'; // for WSL
}
_TERMINAL_DEFAULT_SHELL_UNIX_LIKE = unixLikeTerminal;
}
return _TERMINAL_DEFAULT_SHELL_UNIX_LIKE;
}
let _TERMINAL_DEFAULT_SHELL_WINDOWS: string | null = null;
function getSystemShellWindows(environment: platform.IProcessEnvironment): string {
if (!_TERMINAL_DEFAULT_SHELL_WINDOWS) {
const isAtLeastWindows10 = platform.isWindows && parseFloat(os.release()) >= 10;
const is32ProcessOn64Windows = environment.hasOwnProperty('PROCESSOR_ARCHITEW6432');
const powerShellPath = `${environment.windir}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}\\WindowsPowerShell\\v1.0\\powershell.exe`;
_TERMINAL_DEFAULT_SHELL_WINDOWS = isAtLeastWindows10 ? powerShellPath : processes.getWindowsShell(environment);
}
return _TERMINAL_DEFAULT_SHELL_WINDOWS;
}
let detectedDistro = LinuxDistro.Unknown;
if (platform.isLinux) {
const file = '/etc/os-release';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册