|
|
@ -0,0 +1,564 @@ |
|
|
|
#!/bin/sh |
|
|
|
set -eu |
|
|
|
|
|
|
|
# code-server's automatic install script. |
|
|
|
# See https://github.com/cdr/code-server/blob/master/doc/install.md |
|
|
|
|
|
|
|
usage() { |
|
|
|
arg0="$0" |
|
|
|
if [ "$0" = sh ]; then |
|
|
|
arg0="curl -fsSL https://code-server.dev/install.sh | sh -s --" |
|
|
|
else |
|
|
|
not_curl_usage="The latest script is available at https://code-server.dev/install.sh |
|
|
|
" |
|
|
|
fi |
|
|
|
|
|
|
|
cath << EOF |
|
|
|
Installs code-server for Linux, macOS and FreeBSD. |
|
|
|
It tries to use the system package manager if possible. |
|
|
|
After successful installation it explains how to start using code-server. |
|
|
|
Pass in user@host to install code-server on user@host over ssh. |
|
|
|
The remote host must have internet access. |
|
|
|
${not_curl_usage-} |
|
|
|
Usage: |
|
|
|
$arg0 [--dry-run] [--version X.X.X] [--method detect] \ |
|
|
|
[--prefix ~/.local] [--rsh ssh] [user@host] |
|
|
|
--dry-run |
|
|
|
Echo the commands for the install process without running them. |
|
|
|
--version X.X.X |
|
|
|
Install a specific version instead of the latest. |
|
|
|
--method [detect | standalone] |
|
|
|
Choose the installation method. Defaults to detect. |
|
|
|
- detect detects the system package manager and tries to use it. |
|
|
|
Full reference on the process is further below. |
|
|
|
- standalone installs a standalone release archive into ~/.local |
|
|
|
Add ~/.local/bin to your \$PATH to use it. |
|
|
|
--prefix <dir> |
|
|
|
Sets the prefix used by standalone release archives. Defaults to ~/.local |
|
|
|
The release is unarchived into ~/.local/lib/code-server-X.X.X |
|
|
|
and the binary symlinked into ~/.local/bin/code-server |
|
|
|
To install system wide pass ---prefix=/usr/local |
|
|
|
--rsh <bin> |
|
|
|
Specifies the remote shell for remote installation. Defaults to ssh. |
|
|
|
- For Debian, Ubuntu and Raspbian it will install the latest deb package. |
|
|
|
- For Fedora, CentOS, RHEL and openSUSE it will install the latest rpm package. |
|
|
|
- For Arch Linux it will install the AUR package. |
|
|
|
- For any unrecognized Linux operating system it will install the latest standalone |
|
|
|
release into ~/.local |
|
|
|
- For macOS it will install the Homebrew package. |
|
|
|
- If Homebrew is not installed it will install the latest standalone release |
|
|
|
into ~/.local |
|
|
|
- For FreeBSD, it will install the npm package with yarn or npm. |
|
|
|
- If ran on an architecture with no releases, it will install the |
|
|
|
npm package with yarn or npm. |
|
|
|
- We only have releases for amd64 and arm64 presently. |
|
|
|
- The npm package builds the native modules on postinstall. |
|
|
|
It will cache all downloaded assets into ~/.cache/code-server |
|
|
|
More installation docs are at https://github.com/cdr/code-server/blob/master/doc/install.md |
|
|
|
EOF |
|
|
|
} |
|
|
|
|
|
|
|
echo_latest_version() { |
|
|
|
# https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860 |
|
|
|
version="$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/cdr/code-server/releases/latest)" |
|
|
|
version="${version#https://github.com/cdr/code-server/releases/tag/}" |
|
|
|
version="${version#v}" |
|
|
|
echo "$version" |
|
|
|
} |
|
|
|
|
|
|
|
echo_npm_postinstall() { |
|
|
|
echoh |
|
|
|
cath << EOF |
|
|
|
The npm package has been installed successfully! |
|
|
|
Please extend your path to use code-server: |
|
|
|
PATH="$NPM_BIN_DIR:\$PATH" |
|
|
|
Please run with: |
|
|
|
code-server |
|
|
|
EOF |
|
|
|
} |
|
|
|
|
|
|
|
echo_standalone_postinstall() { |
|
|
|
echoh |
|
|
|
cath << EOF |
|
|
|
Standalone release has been installed into $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION |
|
|
|
Please extend your path to use code-server: |
|
|
|
PATH="$STANDALONE_INSTALL_PREFIX/bin:\$PATH" |
|
|
|
Then you can run: |
|
|
|
code-server |
|
|
|
EOF |
|
|
|
} |
|
|
|
|
|
|
|
echo_systemd_postinstall() { |
|
|
|
echoh |
|
|
|
cath << EOF |
|
|
|
To have systemd start code-server now and restart on boot: |
|
|
|
sudo systemctl enable --now code-server@\$USER |
|
|
|
Or, if you don't want/need a background service you can run: |
|
|
|
code-server |
|
|
|
EOF |
|
|
|
} |
|
|
|
|
|
|
|
main() { |
|
|
|
if [ "${TRACE-}" ]; then |
|
|
|
set -x |
|
|
|
fi |
|
|
|
|
|
|
|
unset \ |
|
|
|
DRY_RUN \ |
|
|
|
METHOD \ |
|
|
|
STANDALONE_INSTALL_PREFIX \ |
|
|
|
VERSION \ |
|
|
|
OPTIONAL \ |
|
|
|
ALL_FLAGS \ |
|
|
|
RSH_ARGS \ |
|
|
|
RSH |
|
|
|
|
|
|
|
ALL_FLAGS="" |
|
|
|
while [ "$#" -gt 0 ]; do |
|
|
|
case "$1" in |
|
|
|
-*) |
|
|
|
ALL_FLAGS="${ALL_FLAGS} $1" |
|
|
|
;; |
|
|
|
esac |
|
|
|
|
|
|
|
case "$1" in |
|
|
|
--dry-run) |
|
|
|
DRY_RUN=1 |
|
|
|
;; |
|
|
|
--method) |
|
|
|
METHOD="$(parse_arg "$@")" |
|
|
|
shift |
|
|
|
;; |
|
|
|
--method=*) |
|
|
|
METHOD="$(parse_arg "$@")" |
|
|
|
;; |
|
|
|
--prefix) |
|
|
|
STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")" |
|
|
|
shift |
|
|
|
;; |
|
|
|
--prefix=*) |
|
|
|
STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")" |
|
|
|
;; |
|
|
|
--version) |
|
|
|
VERSION="$(parse_arg "$@")" |
|
|
|
shift |
|
|
|
;; |
|
|
|
--version=*) |
|
|
|
VERSION="$(parse_arg "$@")" |
|
|
|
;; |
|
|
|
--rsh) |
|
|
|
RSH="$(parse_arg "$@")" |
|
|
|
shift |
|
|
|
;; |
|
|
|
--rsh=*) |
|
|
|
RSH="$(parse_arg "$@")" |
|
|
|
;; |
|
|
|
-h | --h | -help | --help) |
|
|
|
usage |
|
|
|
exit 0 |
|
|
|
;; |
|
|
|
--) |
|
|
|
shift |
|
|
|
# We remove the -- added above. |
|
|
|
ALL_FLAGS="${ALL_FLAGS% --}" |
|
|
|
RSH_ARGS="$*" |
|
|
|
break |
|
|
|
;; |
|
|
|
-*) |
|
|
|
echoerr "Unknown flag $1" |
|
|
|
echoerr "Run with --help to see usage." |
|
|
|
exit 1 |
|
|
|
;; |
|
|
|
*) |
|
|
|
RSH_ARGS="$*" |
|
|
|
break |
|
|
|
;; |
|
|
|
esac |
|
|
|
|
|
|
|
shift |
|
|
|
done |
|
|
|
|
|
|
|
if [ "${RSH_ARGS-}" ]; then |
|
|
|
RSH="${RSH-ssh}" |
|
|
|
echoh "Installing remotely with $RSH $RSH_ARGS" |
|
|
|
curl -fsSL https://code-server.dev/install.sh | prefix "$RSH_ARGS" "$RSH" "$RSH_ARGS" sh -s -- "$ALL_FLAGS" |
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
VERSION="${VERSION-$(echo_latest_version)}" |
|
|
|
METHOD="${METHOD-detect}" |
|
|
|
if [ "$METHOD" != detect ] && [ "$METHOD" != standalone ]; then |
|
|
|
echoerr "Unknown install method \"$METHOD\"" |
|
|
|
echoerr "Run with --help to see usage." |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
STANDALONE_INSTALL_PREFIX="${STANDALONE_INSTALL_PREFIX-$HOME/.local}" |
|
|
|
|
|
|
|
OS="$(os)" |
|
|
|
if [ ! "$OS" ]; then |
|
|
|
echoerr "Unsupported OS $(uname)." |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
|
|
|
|
distro_name |
|
|
|
|
|
|
|
ARCH="$(arch)" |
|
|
|
if [ ! "$ARCH" ]; then |
|
|
|
if [ "$METHOD" = standalone ]; then |
|
|
|
echoerr "No precompiled releases for $(uname -m)." |
|
|
|
echoerr 'Please rerun without the "--method standalone" flag to install from npm.' |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
echoh "No precompiled releases for $(uname -m)." |
|
|
|
install_npm |
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
if [ "$OS" = "freebsd" ]; then |
|
|
|
if [ "$METHOD" = standalone ]; then |
|
|
|
echoerr "No precompiled releases available for $OS." |
|
|
|
echoerr 'Please rerun without the "--method standalone" flag to install from npm.' |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
echoh "No precompiled releases available for $OS." |
|
|
|
install_npm |
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
CACHE_DIR="$(echo_cache_dir)" |
|
|
|
|
|
|
|
if [ "$METHOD" = standalone ]; then |
|
|
|
install_standalone |
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
case "$(distro)" in |
|
|
|
macos) |
|
|
|
install_macos |
|
|
|
;; |
|
|
|
debian) |
|
|
|
install_deb |
|
|
|
;; |
|
|
|
fedora | opensuse) |
|
|
|
install_rpm |
|
|
|
;; |
|
|
|
arch) |
|
|
|
install_aur |
|
|
|
;; |
|
|
|
*) |
|
|
|
echoh "Unsupported package manager." |
|
|
|
install_standalone |
|
|
|
;; |
|
|
|
esac |
|
|
|
} |
|
|
|
|
|
|
|
parse_arg() { |
|
|
|
case "$1" in |
|
|
|
*=*) |
|
|
|
# Remove everything after first equal sign. |
|
|
|
opt="${1%%=*}" |
|
|
|
# Remove everything before first equal sign. |
|
|
|
optarg="${1#*=}" |
|
|
|
if [ ! "$optarg" ] && [ ! "${OPTIONAL-}" ]; then |
|
|
|
echoerr "$opt requires an argument" |
|
|
|
echoerr "Run with --help to see usage." |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
echo "$optarg" |
|
|
|
return |
|
|
|
;; |
|
|
|
esac |
|
|
|
|
|
|
|
case "${2-}" in |
|
|
|
"" | -*) |
|
|
|
if [ ! "${OPTIONAL-}" ]; then |
|
|
|
echoerr "$1 requires an argument" |
|
|
|
echoerr "Run with --help to see usage." |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
;; |
|
|
|
*) |
|
|
|
echo "$2" |
|
|
|
return |
|
|
|
;; |
|
|
|
esac |
|
|
|
} |
|
|
|
|
|
|
|
fetch() { |
|
|
|
URL="$1" |
|
|
|
FILE="$2" |
|
|
|
|
|
|
|
if [ -e "$FILE" ]; then |
|
|
|
echoh "+ Reusing $FILE" |
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
sh_c mkdir -p "$CACHE_DIR" |
|
|
|
sh_c curl \ |
|
|
|
-#fL \ |
|
|
|
-o "$FILE.incomplete" \ |
|
|
|
-C - \ |
|
|
|
"$URL" |
|
|
|
sh_c mv "$FILE.incomplete" "$FILE" |
|
|
|
} |
|
|
|
|
|
|
|
install_macos() { |
|
|
|
if command_exists brew; then |
|
|
|
echoh "Installing from Homebrew." |
|
|
|
echoh |
|
|
|
|
|
|
|
sh_c brew install code-server |
|
|
|
|
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
echoh "Homebrew not installed." |
|
|
|
|
|
|
|
install_standalone |
|
|
|
} |
|
|
|
|
|
|
|
install_deb() { |
|
|
|
echoh "Installing v$VERSION deb package from GitHub releases." |
|
|
|
echoh |
|
|
|
|
|
|
|
fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server_${VERSION}_$ARCH.deb" \ |
|
|
|
"$CACHE_DIR/code-server_${VERSION}_$ARCH.deb" |
|
|
|
sudo_sh_c dpkg -i "$CACHE_DIR/code-server_${VERSION}_$ARCH.deb" |
|
|
|
|
|
|
|
echo_systemd_postinstall |
|
|
|
} |
|
|
|
|
|
|
|
install_rpm() { |
|
|
|
echoh "Installing v$VERSION rpm package from GitHub releases." |
|
|
|
echoh |
|
|
|
|
|
|
|
fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server-$VERSION-$ARCH.rpm" \ |
|
|
|
"$CACHE_DIR/code-server-$VERSION-$ARCH.rpm" |
|
|
|
sudo_sh_c rpm -i "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm" |
|
|
|
|
|
|
|
echo_systemd_postinstall |
|
|
|
} |
|
|
|
|
|
|
|
install_aur() { |
|
|
|
echoh "Installing from the AUR." |
|
|
|
echoh |
|
|
|
|
|
|
|
sh_c mkdir -p "$CACHE_DIR/code-server-aur" |
|
|
|
sh_c "curl -#fsSL https://aur.archlinux.org/cgit/aur.git/snapshot/code-server.tar.gz | tar -xzC $CACHE_DIR/code-server-aur --strip-components 1" |
|
|
|
echo "+ cd $CACHE_DIR/code-server-aur" |
|
|
|
if [ ! "${DRY_RUN-}" ]; then |
|
|
|
cd "$CACHE_DIR/code-server-aur" |
|
|
|
fi |
|
|
|
sh_c makepkg -si |
|
|
|
|
|
|
|
echo_systemd_postinstall |
|
|
|
} |
|
|
|
|
|
|
|
install_standalone() { |
|
|
|
echoh "Installing standalone release archive v$VERSION from GitHub releases." |
|
|
|
echoh |
|
|
|
|
|
|
|
fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server-$VERSION-$OS-$ARCH.tar.gz" \ |
|
|
|
"$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz" |
|
|
|
|
|
|
|
sh_c="sh_c" |
|
|
|
if [ ! -w "$STANDALONE_INSTALL_PREFIX" ]; then |
|
|
|
sh_c="sudo_sh_c" |
|
|
|
fi |
|
|
|
|
|
|
|
if [ -e "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" ]; then |
|
|
|
echoh |
|
|
|
echoh "code-server-$VERSION is already installed at $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" |
|
|
|
echoh "Remove it to reinstall." |
|
|
|
exit 0 |
|
|
|
fi |
|
|
|
|
|
|
|
"$sh_c" mkdir -p "$STANDALONE_INSTALL_PREFIX/lib" "$STANDALONE_INSTALL_PREFIX/bin" |
|
|
|
"$sh_c" tar -C "$STANDALONE_INSTALL_PREFIX/lib" -xzf "$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz" |
|
|
|
"$sh_c" mv -f "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION-$OS-$ARCH" "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" |
|
|
|
"$sh_c" ln -fs "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION/bin/code-server" "$STANDALONE_INSTALL_PREFIX/bin/code-server" |
|
|
|
|
|
|
|
echo_standalone_postinstall |
|
|
|
} |
|
|
|
|
|
|
|
install_npm() { |
|
|
|
if command_exists yarn; then |
|
|
|
sh_c="sh_c" |
|
|
|
if [ ! -w "$(yarn global bin)" ]; then |
|
|
|
sh_c="sudo_sh_c" |
|
|
|
fi |
|
|
|
echoh "Installing with yarn." |
|
|
|
echoh |
|
|
|
"$sh_c" yarn global add code-server --unsafe-perm |
|
|
|
NPM_BIN_DIR="$(yarn global bin)" echo_npm_postinstall |
|
|
|
return |
|
|
|
elif command_exists npm; then |
|
|
|
sh_c="sh_c" |
|
|
|
if [ ! -w "$(npm config get prefix)" ]; then |
|
|
|
sh_c="sudo_sh_c" |
|
|
|
fi |
|
|
|
echoh "Installing with npm." |
|
|
|
echoh |
|
|
|
"$sh_c" npm install -g code-server --unsafe-perm |
|
|
|
NPM_BIN_DIR="$(npm bin -g)" echo_npm_postinstall |
|
|
|
return |
|
|
|
fi |
|
|
|
echoh |
|
|
|
echoerr "Please install npm or yarn to install code-server!" |
|
|
|
echoerr "You will need at least node v12 and a few C dependencies." |
|
|
|
echoerr "See the docs https://github.com/cdr/code-server#yarn-npm" |
|
|
|
exit 1 |
|
|
|
} |
|
|
|
|
|
|
|
os() { |
|
|
|
case "$(uname)" in |
|
|
|
Linux) |
|
|
|
echo linux |
|
|
|
;; |
|
|
|
Darwin) |
|
|
|
echo macos |
|
|
|
;; |
|
|
|
FreeBSD) |
|
|
|
echo freebsd |
|
|
|
;; |
|
|
|
esac |
|
|
|
} |
|
|
|
|
|
|
|
# distro prints the detected operating system including linux distros. |
|
|
|
# Also parses ID_LIKE for common distro bases. |
|
|
|
# |
|
|
|
# Example outputs: |
|
|
|
# - macos -> macos |
|
|
|
# - freebsd -> freebsd |
|
|
|
# - ubuntu, raspbian, debian ... -> debian |
|
|
|
# - amzn, centos, rhel, fedora, ... -> fedora |
|
|
|
# - opensuse-{leap,tumbleweed} -> opensuse |
|
|
|
# - alpine -> alpine |
|
|
|
# - arch -> arch |
|
|
|
# |
|
|
|
# Inspired by https://github.com/docker/docker-install/blob/26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c/install.sh#L111-L120. |
|
|
|
distro() { |
|
|
|
if [ "$OS" = "macos" ] || [ "$OS" = "freebsd" ]; then |
|
|
|
echo "$OS" |
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
if [ -f /etc/os-release ]; then |
|
|
|
( |
|
|
|
. /etc/os-release |
|
|
|
if [ "${ID_LIKE-}" ]; then |
|
|
|
for id_like in $ID_LIKE; do |
|
|
|
case "$id_like" in debian | fedora | opensuse) |
|
|
|
echo "$id_like" |
|
|
|
return |
|
|
|
;; |
|
|
|
esac |
|
|
|
done |
|
|
|
fi |
|
|
|
|
|
|
|
echo "$ID" |
|
|
|
) |
|
|
|
return |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
# os_name prints a pretty human readable name for the OS/Distro. |
|
|
|
distro_name() { |
|
|
|
if [ "$(uname)" = "Darwin" ]; then |
|
|
|
echo "macOS v$(sw_vers -productVersion)" |
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
if [ -f /etc/os-release ]; then |
|
|
|
( |
|
|
|
. /etc/os-release |
|
|
|
echo "$PRETTY_NAME" |
|
|
|
) |
|
|
|
return |
|
|
|
fi |
|
|
|
|
|
|
|
# Prints something like: Linux 4.19.0-9-amd64 |
|
|
|
uname -sr |
|
|
|
} |
|
|
|
|
|
|
|
arch() { |
|
|
|
case "$(uname -m)" in |
|
|
|
aarch64) |
|
|
|
echo arm64 |
|
|
|
;; |
|
|
|
x86_64) |
|
|
|
echo amd64 |
|
|
|
;; |
|
|
|
amd64) # FreeBSD. |
|
|
|
echo amd64 |
|
|
|
;; |
|
|
|
esac |
|
|
|
} |
|
|
|
|
|
|
|
command_exists() { |
|
|
|
command -v "$@" > /dev/null |
|
|
|
} |
|
|
|
|
|
|
|
sh_c() { |
|
|
|
echoh "+ $*" |
|
|
|
if [ ! "${DRY_RUN-}" ]; then |
|
|
|
sh -c "$*" |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
sudo_sh_c() { |
|
|
|
if [ "$(id -u)" = 0 ]; then |
|
|
|
sh_c "$@" |
|
|
|
elif command_exists sudo; then |
|
|
|
sh_c "sudo $*" |
|
|
|
elif command_exists su; then |
|
|
|
sh_c "su -c '$*'" |
|
|
|
else |
|
|
|
echoh |
|
|
|
echoerr "This script needs to run the following command as root." |
|
|
|
echoerr " $*" |
|
|
|
echoerr "Please install sudo or su." |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
echo_cache_dir() { |
|
|
|
if [ "${XDG_CACHE_HOME-}" ]; then |
|
|
|
echo "$XDG_CACHE_HOME/code-server" |
|
|
|
elif [ "${HOME-}" ]; then |
|
|
|
echo "$HOME/.cache/code-server" |
|
|
|
else |
|
|
|
echo "/tmp/code-server-cache" |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
echoh() { |
|
|
|
echo "$@" | humanpath |
|
|
|
} |
|
|
|
|
|
|
|
cath() { |
|
|
|
humanpath |
|
|
|
} |
|
|
|
|
|
|
|
echoerr() { |
|
|
|
echoh "$@" >&2 |
|
|
|
} |
|
|
|
|
|
|
|
# humanpath replaces all occurances of " $HOME" with " ~" |
|
|
|
# and all occurances of '"$HOME' with the literal '"$HOME'. |
|
|
|
humanpath() { |
|
|
|
sed "s# $HOME# ~#g; s#\"$HOME#\"\$HOME#g" |
|
|
|
} |
|
|
|
|
|
|
|
# We need to make sure we exit with a non zero exit if the command fails. |
|
|
|
# /bin/sh does not support -o pipefail unfortunately. |
|
|
|
prefix() { |
|
|
|
PREFIX="$1" |
|
|
|
shift |
|
|
|
fifo="$(mktemp -d)/fifo" |
|
|
|
mkfifo "$fifo" |
|
|
|
sed -e "s#^#$PREFIX: #" "$fifo" & |
|
|
|
"$@" > "$fifo" 2>&1 |
|
|
|
} |
|
|
|
|
|
|
|
main "$@" |