Skip to content

Instantly share code, notes, and snippets.

@gocha
Last active January 30, 2018 07:25
Show Gist options
  • Save gocha/15d5032e5a2eba55e32546c1a1d96cdd to your computer and use it in GitHub Desktop.
Save gocha/15d5032e5a2eba55e32546c1a1d96cdd to your computer and use it in GitHub Desktop.
Advanced runwin32 launcher for Cygwin+rsh w/ iconv charset conversion
#!/bin/bash
#
# Note:
# - Environment variables must be set before running. This script doesn't import any user profiles.
# Add Windows system directory paths to the PATH,
# to allow to use cmd.exe and any other standard commands.
export PATH="$(cygpath -S):$(cygpath -W):$PATH"
# Add some common system variables.
#
# You may want this section, only if you're running the script via remote shell,
# since the rsh daemon doesn't import Windows environment variables at all.
#[ ! -v COMPUTERNAME ] && export COMPUTERNAME="$(hostname)"
#[ ! -v SYSTEMDRIVE ] && export SYSTEMDRIVE="$(cygpath -w -W | cut -f1 -d '\')"
#[ ! -v TEMP ] && export TEMP="$(cygpath -w -F 0x001c)\Temp"
#[ ! -v TMP ] && export TMP="$TEMP"
#[ ! -v USERNAME ] && export USERNAME="$(id -un)"
#[ ! -v USERPROFILE ] && export USERPROFILE="$(cygpath -w -F 0x0028)"
# Run specified command line.
#
# Known Issue:
# When Cygwin launches a Win32 process, its arguments are escaped by MSVC escaping rule.
# Thus, commands which follow an another escaping rule may get unexpected value.
#
# For example, built-in shell commands (such as dir) doesn't follow MSVC escaping rule.
# `dir "C:\Program Files\"` will get replaced by dir `"C:\Program Files\\"`
# and such a conversion sometimes may cause an error.
# Convert the character encodings of both stdout and stderr in real time.
# (by passing these streams to iconv. Uses bash process substitution for that.)
#
# These iconv processes however runs asynchronously.
# To wait for them, a named pipe will be created and used.
pipename=$(mktemp -u --tmpdir runwin32-XXXXXX.pipe)
mkfifo $pipename
# Make sure the named pipe will be deleted on exit.
# (even if it's interrupted by user!)
trap "if [ -p $pipename ]; then rm $pipename; fi" EXIT
# Run specified command line.
# Write a blank line to the named pipe, when iconv has exited.
$(cygpath "$SYSTEMROOT\\System32\\cmd.exe") /c "$@" \
> >(iconv -f cp932 -t utf8; echo >$pipename) \
2> >(iconv -f cp932 -t utf8 >&2; echo >$pipename)
status=$PIPESTATUS
# Wait for iconv, by waiting for the blank line inputs.
read line < $pipename
read line < $pipename
# Return the exit status.
exit $status
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment