タイトルからほとんどの質問がわかるように、最後に明示的なサフィックスを指定せずに.exe
Windowsの実行可能ファイルをどのように実行できますか?
explorer.exe .
たとえば、、、、、explorer .
またはnotepad.exe file
で、および他の呼び出しを減らします。notepad file
docker.exe ps
docker ps
これを行う基本的な方法があるか、command not found
コマンド名に利用可能なLinuxプログラムがない場合は、エラーを処理して実行可能ファイルにリダイレクトする方法があるかどうか疑問に思います。.exe
$Path
編集する:
以前は環境を追加するのを忘れていました。ここにあります:
- ターミナル:Windowsターミナル
- Linux:WSLのUbuntu 20.04(Linux用Windowsサブシステム)
- シェル:zsh
- オペレーティングシステム:Windows 10 1909
答え1
設定できますcommand_not_found_handler
。テストされていません:
function command_not_found_handler {
for ext in ${(s:;:)${PATHEXT-".com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc"}}; do
if (( $+commands[$1$ext] )); then
exec -- "$1$ext" "${@:2}"
fi
done
print -ru2 "command not found: $1"
return 127
}
これはfoo.exe
(または他の拡張機能など.bat
)機能しますがfoo
。foo.exe
zshでは機能しませんが、foo
cmdでは機能し、名前付きプログラムを呼び出す場合は、foo.exe
他の問題があります。
答え2
3つのオプションがあります。
常に入力してください
.exe
。シェルにコマンド補完機能があると仮定すると、役に立ちます。しかし、それはあなたが避けたいものです。他の人はエイリアスソリューションを指摘しました。
.exeなしでWindows実行可能ファイルへのシンボリックリンクを作成します。これはパス(Unix / Linuxファイルシステム)のディレクトリに配置する必要があります。 (このディレクトリへのパスにディレクトリを追加したい場合があります。)おそらく、次のようにします。
cd ~/bin.windows_exes ln -s /path/to/windows/executables/*.exe . prename 's/.exe$//' *.exe
(
prename
はいperl
バージョンですrename
。これはrename
私が知って使用しているバージョンです。)次に、次のようにパスに追加します。
PATH="$PATH":"$HOME"/bin.windows_exe
編集:明らかにOPはインストールスクリプトを望んでいました。ここで拒否された後(同意します。少し単純です。)OPが自分の答えで投稿し、小切手をそこに移したので、直接作成しました。私はBourneシェル派生と互換性があるようにUnixバージョン7に従おうとしました。
これには、出力ディレクトリの設定、リストの拡張、冗長または自動実行、リンクの削除などのオプションが含まれます。壊れたリンクを置き換えない限り、既存のコンテンツを上書きしないように注意してください。
上部の拡張ディレクトリとデフォルト出力ディレクトリのリストは、下部に接続されているデフォルトのWindowsディレクトリのリストと同様に編集できます。 (後者の場合は、MS-Windowsドライブがにマウントされているとします/windows
。)MS-Windowsパスにあるディレクトリをこのリストに追加することを検討できます。
#!/bin/sh
exts='exe bat cmd com vbs vbe js jse wsf wsh msc'
output_directory="$HOME/.windows_binaries"
quiet=false
verbose=false
dryrun=false
remove=false
debug=false
usage() {
echo "`basename "$0"`" '<options>' '[<windows_directories>]'
echo ' -d dir Specify the output directory'
echo ' -e ext Add a windows extension, like "exe"'
echo ' -E Clear the list of extensions'
echo ' -v, --verbose Verbose (report normal changes)'
echo ' -q, --quiet Quiet (don'"'"'t report errors)'
echo ' -n, --dryrun Do not make any changes'
echo ' --remove Remove links that would otherwise be made'
(
echo 'If no windows directories are specified,'
echo 'everything in the PATH is done implicitly.'
echo 'For Cygwin'
echo 'or Microsoft'"'"'s "Windows Subsystem for Linux",'
echo 'it is assumed'
echo 'that PATH has been translated to Unix conventions.'
) | fmt
exit 2
}
add_link() {
$debug && echo consider "$1" "$2"
if test -h "$2"
then
# here, the target already exists, and is a link
oldlink="`readlink "$2"`"
if test "$1" = "$oldlink"
then
if $remove
then
$verbose && echo remove "$2"
$dryrun || rm "$2"
fi
else
if $remove
then
:
else
if test ! -e "$2"
then
# old link broken, replace it
$dryrun || rm "$2"
$dryrun || ln -s "$1" "$2"
$verbose && echo replace broken "$2" as "$1"
else
$quiet || echo "$2" already links to "$oldlink" -- not changing it to "$1"
fi
fi
fi
elif $remove
then
:
elif test -e "$2"
then
# here, the target already exists
$quiet || echo Not replacing file "$2"
else
# here, the target does not exist
$dryrun || ln -s "$1" "$2"
$verbose && echo link "$2" as "$1"
fi
}
add_directory() {
dir="$1"
case "$dir" in
*/) dir="` expr "$dir" : '\(*\)/' `" ;;
esac
$debug && echo consider "$1"
for ext in $exts
do
for path in "$dir"/*."$ext"
do
# wildcards in bourne shell always return something, even if it is just the wildcard
if test -f "$path"
then
fn=`basename "$path" ."$ext"`
add_link "$path" "$output_directory"/"$fn"
fi
done
done
}
## Can't use getopt because it doesn't handle spaces, and windows directories
## are notorious for having spaces. Can't use getopts as it is too recent.
have_dirs=
mode=
for arg in "$@"
do
case "$mode":"$arg" in
:-d) mode=-d ;;
:-d*) output_directory="`expr "$arg" : "-d\(*\)"`" ;;
-d:*) output_directory="$arg" mode= ;;
:-e) mode=-e ;;
:-e*) exts="$exts `expr "$arg" : "-d\(*\)"`" ;;
-e:*) exts="$exts $arg" mode= ;;
:-E) exts="" ;;
:-q) quiet=true ;;
:--quiet) quiet=true ;;
:-v) verbose=true ;;
:--verbose) verbose=true ;;
:-n) dryrun=true ;;
:--dryrun) dryrun=true ;;
:--remove) remove=true ;;
:-*) echo Bad option "$arg" ; usage ;;
:*)
if test -d "$arg"
then
have_dirs=true
else
echo Argument "$arg" is not a directory
usage
fi
;;
esac
done
if test -z "$exts"
then
echo No extensions specified '(and you cleared the list)'
usage
fi
if test ! -d "$output_directory"
then
if $remove
then
echo Nothing to do
exit 0
fi
mkdir "$output_directory"
$verbose && echo made directory "$output_directory"
fi
if test -n "$have_dirs"
then
mode=
for arg in "$@"
do
case "$mode":"$arg" in
:-[de]) mode=$arg ;;
:-[de]*) ;;
-[de]:*) mode= ;;
:-[Eqvn]) ;;
:--quiet) ;;
:--verbose) ;;
:--dryrun) ;;
:--remove) ;;
:*) add_directory "$arg" ;;
esac
done
else
# Do all the directories in the path.
IFS0="$IFS"
IFS=:
for pdir in $PATH
do
IFS="$IFS0"
add_directory "$pdir"
done
fi
$remove && rmdir "$output_directory" 2>/dev/null
$verbose && test ! -d "$output_directory" && echo remove directory "$output_directory"
編集:PATH変数を使用するようにスクリプトを変更しました。 OPの質問に示されているのは、彼がパスで使用したいすべてのWindows実行可能ディレクトリを取得したことです。
答え3
にエイリアスを作成します.zshrc
。
alias docker='docker.exe'
その後source
は行ってもいいです。必要な実行可能ファイルに対してのみこれを実行することをお勧めします。結局のところ、あなたはおそらく.NETのping
代わりにLinuxを実行したいと思いますping.exe
。
答え4
@DavidGが提供したアイデアに従います。私が作りました。誰かが幸せになることを願っています:)
次のスクリプトは、Windows上のすべての実行可能ファイルが存在しない場合、欠落しているディレクトリとシンボリックリンクを生成します。
#!/usr/bin/zsh
mkdir -p $HOME/.windows_binaries
cd $HOME/.windows_binaries
for ext in $( echo ${PATHEXT-".com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc"} | tr \; ' ' ); do
for command in ${(M)commands:#*$ext}; do
if [ -f $(basename $command $ext) ]; then; else
ln -s $command $(basename $command $ext)
fi
done
done
~/.windows_binaries
その後、Linux実行可能ファイルが見つからない場合は、Windows実行可能ファイルがトリガーされるようにフォルダをパスに追加できます。
$HOME/.zshrc
ファイルから:
export PATH=$PATH:$HOME/.windows_binaries
上記のスクリプトの説明:
#!/usr/bin/zsh
- Shebangはbashでデフォルトで使用できないフィルタリングコマンドを使用するため、zshで実行するようにスクリプトをリダイレクトします。mkdir -p $HOME/.windows_binaries
- パスが存在しない場合は生成してください:)cd $HOME/.windows_binaries
- cwdをそれに変更for ext in $(...); do
- スクリプトと見なされるウィンドウの各拡張を繰り返します。for command in ${(M)commands:#*$ext}; do
$commands
– 現在のシェルで使用可能なすべてのコマンドをインデックス化し、zsh フィルタを使用して拡張子$ext
で終わるコマンドをフィルタリングします。if [ -f $(basename $command $ext) ]; then; else
- 拡張子のないコマンドへのシンボリックリンクが作成されている場合はスキップし、そうでない場合はを使用して生成を続けますln -s
。
編集する:
スクリプトの最適化に役立つ @user414777 ありがとうございます。今は約2-3倍速くなりました(7-9秒)。
#!/usr/bin/zsh
mkdir -p $HOME/.windows_binaries
cd $HOME/.windows_binaries
all_exts=${${${PATHEXT-".com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc"}//;/|}//./}
IFS=$'\n'
if [ $ZSH_VERSION ]; then setopt sh_word_split; fi
for command in $(whence -psm "*.($all_exts)"); do
sym_name=${${command##*/}%.*}
if [ -f $sym_name ]; then; else
ln -s $command $sym_name
fi
done
tr
また、正規表現の置換/文字列の変更シェルの交換は、たとえばパイプで接続するよりも優れており、交換を拡張するためにIFSがzshで直接使用されないことを学びました。