定义在Windows和Linux上工作的通用别名(Windows bash或Cygwin)



我在windows 10操作系统中使用"Window Command shell"one_answers"Bash shell"。真正让我恼火的是,我必须为每个shell定义别名(doskey&alias(,即使我使用相同的命令&文件夹别名。例如alias np='D:_MyProgram_IDE编辑器\记事本++\记事本++.exe'doskey np=D:_MyProgram_ID编辑器\记事本++\记事本++.exe$*

因此,我想知道如何定义在两个shell中都能工作的通用定义目前我的想法是。。。

  1. 定义通用定义文本文件
  2. 制作一个脚本,读取"公共定义文件"并定义"命令中的doskey"one_answers"Bash-shell中的别名">

有没有好的方法来做这件事或任何相关的工作?

示例(

1. define common definition text file (common-define.txt)
"SET"   "DIR_PROGRAM"   "D:OneDrive_MyProgram"
"CD" "dev"              "D:OneDrive_MyProgram"
"ALIAS" "tt"            "tt.bat"

2. read it and define "doskey in commands", and "alias in shell" (autoload-batch.bat)
FOR /f "tokens=1,2,3* delims= " %%A IN ( common.define.txt
) DO (
if "%%~A"=="###"    echo %%A, %%B, %%C
if "%%~A"=="SET"    set %%~B=%%~C
if "%%~A"=="SETX"   setx %%~B %%~C
if "%%~A"=="CD"     echo @doskey %%~B=cd /d %%~C>>gen_doskey.cmd
if "%%~A"=="ALIAS"  echo @doskey %%~B=%%~C $*>>gen_doskey.cmd
)
reg add "hkcusoftwaremicrosoftcommand processor" /v Autorun /t reg_sz /d %~dp0gen_doskey.cmd /f

这是windows版本。我正在开发linux版本。我想做这件事,有什么好办法吗?

本机Linux,翻译为doskey

我相信我已经成功地创建了一个batch+bash多语言脚本。使用bash shell保存此,以便行仅以LF终止,而不是以Windows样式的CRLF终止。cmd似乎比bash更能接受Unix风格的行终止。

: <<'BASH_PORTION'
@goto batch
BASH_PORTION
# aliases
alias hello="echo Hello world!"
alias ls="dir"
: <<'BATCH_PORTION'
:batch
@echo off & setlocal
for /f "tokens=2* delims== " %%I in (
'findstr "^alias" "%~f0"'
) do doskey %%~I=%%~J
exit /b
BATCH_PORTION

然后,要获取脚本的源代码,请在bash脚本中执行source scriptfile.bat。事实上,当您启动一个新的bash会话时,这就是~/.bashrc和~/.profile的来源。在cmd shell中,您可以只执行scriptfile.bat

神奇之处在于精心放置heredoc多行注释。bash解释器将: <<'BASH_PORTION'视为多行注释的开始,将BASH_PORTION视为其结束。我从这个答案中得到了这个想法。使用这些heredoc注释,bash可以被强制忽略cmd批处理行。批处理将任何以:开头的行作为标签,因此第一行没有任何效果。

在解决了欺骗每个解释器忽略对方命令的问题后,剩下的就是定义别名了。别名必须在bash端使用双引号定义,然后可以在批处理端使用for /f循环剥离引号,aliasdoskey替换。


本机doskey,为Linux翻译

或者,您可以像往常一样创建一个doskey格式的宏文件,比如:

hi=echo Hello $*
bye=echo Goodbye $*

要将宏加载到cmd控制台,只需

doskey /macrofile="pathtomacrofile"

如果您愿意,可以将其放入自动运行值中的"HKLM\SOFTWARE\Microsoft\Command Processor"中。

要在Linux子系统中加载宏,需要进行一些翻译和源代码处理。类似的东西会进入你的~/.bashrc:

t=$(mktemp -p /dev/shm)
awk -v RS='rn' -F= '{print $1"(){ "$2"; }"}'</mnt/c/Users/path/to/macros.doskey >$t
source $t
rm -f $t
unset t

不幸的是,我还没能找到一个使用eval来定义函数或别名的解决方案——我猜是因为eval产生了一个新的shell,它不会将环境更改传递给调用范围。所以临时文件似乎是必需的。


添加文件路径转换的示例

使用第二种方法,如果您想将Windows文件系统路径转换为Linux表示法,可以通过添加几个gsub命令来实现。以以下宏.doskey为例:

hi=echo Hello $*
bye=echo Goodbye $*
desktop=pushd "c:Usersusernamedesktop" && dir && popd

在Windows端,您仍然可以使用相同的源代码。

doskey /macrofile="pathtomacros.doskey"

在Linux方面,您可以将以下内容放在.bashrc或类似文件中,在其中使用source filename:进行评估

alias dir='ls --color=auto'
t=$(mktemp -p /dev/shm)
awk -v RS='rn' -F= '
{
gsub(/[A-Za-z]:\/, "/mnt/&")
gsub(/\|:/,"/")
print $1"(){ "$2"; }"
}
'</mnt/c/path/to/macros.doskey >$t
source $t
rm -f $t
unset t

这将用forward替换所有反斜杠,用/mnt/c/和类似的替换c:\,并使用按摩数据创建函数。需要注意的一件大事是,宏文件中的驱动器号的大小写必须与/mnt中的大小写相同。此外,我还使用gawk测试了这些脚本。默认情况下,许多Linux发行版都使用mawk作为包含的awk intelpreter。我试着让脚本变得不可知,但我不确定我是否成功了。无论如何,从您选择的发行版存储库中安装gawk并删除mawk可能是个好主意。mawk是awk的一个最低限度的实现,缺少很多功能。

最新更新