首页 > 解决方案 > cygwin、bash、sed 和 export 引起的奇怪行为

问题描述

对不起。我被这个问题困扰到凌晨 3 点才上床睡觉。当时我的大脑一片混乱,旧的问题描述一团糟。我已经重写了问题描述并删除了旧的。


我发现了一个关于 cygwin、bash、sed 和 export 的奇怪行为。将以下代码保存到文件中,例如 /r/a.sh

echo PATH is $PATH
echo the sed in use is `which sed`

echo 1 | sed 's|1|22|g'

result=`echo 1 | sed 's|1|22|g'`
echo \`xxx\` without export
echo the result is \"$result\"
echo \`xxx\` with export
export result=`echo 1 | sed 's|1|22|g'`
echo the result is \"$result\"
echo \$\(xxx\) without export
result="$(echo 1 | sed 's|1|22|g')"
echo the result is \"$result\"
echo \$\(xxx\) with export
export result="$(echo 1 | sed 's|1|22|g')"
echo the result is \"$result\"

read

所有四种情况的预期结果为 22。这对于我尝试过的大多数环境都是如此,例如 Debian、zsh 和在 conemu 中运行 bash。在 conemu 中,结果是:

PATH is /usr/local/bin:/usr/bin:/d/PortableAppsLocal/ConEmu/ConEmu/Scripts:/d/PortableAppsLocal/ConEmu:/d/PortableAppsLocal/ConEmu/ConEmu:/c/Program Files (x86)/Intel/MPI-RT/4.1.3.045/em64t/bin:/c/Program Files (x86)/Intel/MPI-RT/4.1.3.045/ia32/bin:/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/c/ProgramData/Oracle/Java/javapath:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/ProgramData/chocolatey/bin:/c/Program Files (x86)/GNU/GnuPG/pub:/c/Program Files/IBM/Bluemix/bin:/c/Program Files/MATLAB/R2018a/runtime/win64:/c/Program Files/MATLAB/R2018a/bin:/c/Program Files/Git/cmd:/c/Program Files (x86)/Subversion/bin:/c/WINDOWS/System32/OpenSSH:/c/Program Files/OpenVPN/bin:/c/Program Files (x86)/STMicroelectronics/STM32 ST-LINK Utility/ST-LINK Utility:/c/Users/user/AppData/Local/Microsoft/WindowsApps:/d/Cloud/Win+R:/usr/bin:/d/Python/Python36:/d/Python/Python36/Scripts:/c/Program Files/Oracle/VirtualBox:/d/PortableAppsLocal/bin:/d/Python/Python27:/d/Python/Python27/Scripts:/c/Program Files (x86)/Subversion/bin:/c/Program Files/LLVM/bin:/d/gccarm/bin:/c/Program Files/Java/jre1.8.0_172/bin:/d/lint:/c/Users/user/AppData/Local/atom/bin:/c/Program Files/Microsoft VS Code/bin
the sed in use is /usr/bin/sed
22
`xxx` without export
the result is "22"
`xxx` with export
the result is "22"
$(xxx) without export
the result is "22"
$(xxx) with export
the result is "22"

但是,如果我通过 D:\cygwin64\bin\bash.exe --login /r/a.sh 运行它,结果是

PATH is /usr/local/bin:/usr/bin:/c/Program Files (x86)/Intel/MPI-RT/4.1.3.045/em64t/bin:/c/Program Files (x86)/Intel/MPI-RT/4.1.3.045/ia32/bin:/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/c/ProgramData/Oracle/Java/javapath:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/ProgramData/chocolatey/bin:/c/Program Files (x86)/GNU/GnuPG/pub:/c/Program Files/IBM/Bluemix/bin:/c/Program Files/MATLAB/R2018a/runtime/win64:/c/Program Files/MATLAB/R2018a/bin:/c/Program Files/Git/cmd:/c/Program Files (x86)/Subversion/bin:/c/WINDOWS/System32/OpenSSH:/c/Program Files/OpenVPN/bin:/c/Program Files (x86)/STMicroelectronics/STM32 ST-LINK Utility/ST-LINK Utility:/c/Users/user/AppData/Local/Microsoft/WindowsApps:/d/Cloud/Win+R:/usr/bin:/d/Python/Python36:/d/Python/Python36/Scripts:/c/Program Files/Oracle/VirtualBox:/d/PortableAppsLocal/bin:/d/Python/Python27:/d/Python/Python27/Scripts:/c/Program Files (x86)/Subversion/bin:/c/Program Files/LLVM/bin:/d/gccarm/bin:/c/Program Files/Java/jre1.8.0_172/bin:/d/lint:/c/Users/user/AppData/Local/atom/bin:/c/Program Files/Microsoft VS Code/bin
the sed in use is /usr/bin/sed
22
`xxx` without export
the result is ""
`xxx` with export
the result is "22"
$(xxx) without export
the result is ""
$(xxx) with export
the result is ""

我也尝试过使用 sed 的绝对路径。

echo run with absolute path /sed/bin

echo 1 | sed 's|1|22|g'

result=`echo 1 | /bin/sed 's|1|22|g'`
echo \`xxx\` without export
echo the result is \"$result\"
echo \`xxx\` with export
export result=`echo 1 | /bin/sed 's|1|22|g'`
echo the result is \"$result\"
echo \$\(xxx\) without export
result="$(echo 1 | /bin/sed 's|1|22|g')"
echo the result is \"$result\"
echo \$\(xxx\) with export
export result="$(echo 1 | /bin/sed 's|1|22|g')"
echo the result is \"$result\"

read

结果还是

run with absolute path /sed/bin
22
`xxx` without export
the result is ""
`xxx` with export
the result is "22"
$(xxx) without export
the result is ""
$(xxx) with export
the result is ""

我也试过不带--login运行它,结果是一样的。

总之,有四种情况,只有 export result=xxx按预期工作。


我尝试在脚本开头添加 set -x,结果是

C:\Users\user>D:\cygwin64\bin\bash.exe --login /r/a.sh
+ echo PATH is /usr/local/bin:/usr/bin:/c/Program Files '(x86)/Intel/MPI-RT/4.1.3.045/em64t/bin:/c/Program' Files '(x86)/Intel/MPI-RT/4.1.3.045/ia32/bin:/c/Program' Files '(x86)/Common' Files/Oracle/Java/javapath:/c/ProgramData/Oracle/Java/javapath:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/ProgramData/chocolatey/bin:/c/Program Files '(x86)/GNU/GnuPG/pub:/c/Program' Files/IBM/Bluemix/bin:/c/Program Files/MATLAB/R2018a/runtime/win64:/c/Program Files/MATLAB/R2018a/bin:/c/Program Files/Git/cmd:/c/Program Files '(x86)/Subversion/bin:/c/WINDOWS/System32/OpenSSH:/c/Program' Files/OpenVPN/bin:/c/Program Files '(x86)/STMicroelectronics/STM32' ST-LINK Utility/ST-LINK Utility:/c/Users/user/AppData/Local/Microsoft/WindowsApps:/d/Cloud/Win+R:/usr/bin:/d/Python/Python36:/d/Python/Python36/Scripts:/c/Program Files/Oracle/VirtualBox:/d/PortableAppsLocal/bin:/d/Python/Python27:/d/Python/Python27/Scripts:/c/Program Files '(x86)/Subversion/bin:/c/Program' Files/LLVM/bin:/d/gccarm/bin:/c/Program Files/Java/jre1.8.0_172/bin:/d/lint:/c/Users/user/AppData/Local/atom/bin:/c/Program Files/Microsoft VS Code/bin
PATH is /usr/local/bin:/usr/bin:/c/Program Files (x86)/Intel/MPI-RT/4.1.3.045/em64t/bin:/c/Program Files (x86)/Intel/MPI-RT/4.1.3.045/ia32/bin:/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/c/ProgramData/Oracle/Java/javapath:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/ProgramData/chocolatey/bin:/c/Program Files (x86)/GNU/GnuPG/pub:/c/Program Files/IBM/Bluemix/bin:/c/Program Files/MATLAB/R2018a/runtime/win64:/c/Program Files/MATLAB/R2018a/bin:/c/Program Files/Git/cmd:/c/Program Files (x86)/Subversion/bin:/c/WINDOWS/System32/OpenSSH:/c/Program Files/OpenVPN/bin:/c/Program Files (x86)/STMicroelectronics/STM32 ST-LINK Utility/ST-LINK Utility:/c/Users/user/AppData/Local/Microsoft/WindowsApps:/d/Cloud/Win+R:/usr/bin:/d/Python/Python36:/d/Python/Python36/Scripts:/c/Program Files/Oracle/VirtualBox:/d/PortableAppsLocal/bin:/d/Python/Python27:/d/Python/Python27/Scripts:/c/Program Files (x86)/Subversion/bin:/c/Program Files/LLVM/bin:/d/gccarm/bin:/c/Program Files/Java/jre1.8.0_172/bin:/d/lint:/c/Users/user/AppData/Local/atom/bin:/c/Program Files/Microsoft VS Code/bin

C:\Users\user>D:\cygwin64\bin\bash.exe --login /r/a.sh
+ echo PATH is /usr/local/bin:/usr/bin:/c/Program Files '(x86)/Intel/MPI-RT/4.1.3.045/em64t/bin:/c/Program' Files '(x86)/Intel/MPI-RT/4.1.3.045/ia32/bin:/c/Program' Files '(x86)/Common' Files/Oracle/Java/javapath:/c/ProgramData/Oracle/Java/javapath:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/ProgramData/chocolatey/bin:/c/Program Files '(x86)/GNU/GnuPG/pub:/c/Program' Files/IBM/Bluemix/bin:/c/Program Files/MATLAB/R2018a/runtime/win64:/c/Program Files/MATLAB/R2018a/bin:/c/Program Files/Git/cmd:/c/Program Files '(x86)/Subversion/bin:/c/WINDOWS/System32/OpenSSH:/c/Program' Files/OpenVPN/bin:/c/Program Files '(x86)/STMicroelectronics/STM32' ST-LINK Utility/ST-LINK Utility:/c/Users/user/AppData/Local/Microsoft/WindowsApps:/d/Cloud/Win+R:/usr/bin:/d/Python/Python36:/d/Python/Python36/Scripts:/c/Program Files/Oracle/VirtualBox:/d/PortableAppsLocal/bin:/d/Python/Python27:/d/Python/Python27/Scripts:/c/Program Files '(x86)/Subversion/bin:/c/Program' Files/LLVM/bin:/d/gccarm/bin:/c/Program Files/Java/jre1.8.0_172/bin:/d/lint:/c/Users/user/AppData/Local/atom/bin:/c/Program Files/Microsoft VS Code/bin
PATH is /usr/local/bin:/usr/bin:/c/Program Files (x86)/Intel/MPI-RT/4.1.3.045/em64t/bin:/c/Program Files (x86)/Intel/MPI-RT/4.1.3.045/ia32/bin:/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/c/ProgramData/Oracle/Java/javapath:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/ProgramData/chocolatey/bin:/c/Program Files (x86)/GNU/GnuPG/pub:/c/Program Files/IBM/Bluemix/bin:/c/Program Files/MATLAB/R2018a/runtime/win64:/c/Program Files/MATLAB/R2018a/bin:/c/Program Files/Git/cmd:/c/Program Files (x86)/Subversion/bin:/c/WINDOWS/System32/OpenSSH:/c/Program Files/OpenVPN/bin:/c/Program Files (x86)/STMicroelectronics/STM32 ST-LINK Utility/ST-LINK Utility:/c/Users/user/AppData/Local/Microsoft/WindowsApps:/d/Cloud/Win+R:/usr/bin:/d/Python/Python36:/d/Python/Python36/Scripts:/c/Program Files/Oracle/VirtualBox:/d/PortableAppsLocal/bin:/d/Python/Python27:/d/Python/Python27/Scripts:/c/Program Files (x86)/Subversion/bin:/c/Program Files/LLVM/bin:/d/gccarm/bin:/c/Program Files/Java/jre1.8.0_172/bin:/d/lint:/c/Users/user/AppData/Local/atom/bin:/c/Program Files/Microsoft VS Code/bin
++ which sed
+ echo the sed in use is /usr/bin/sed
the sed in use is /usr/bin/sed
+ echo 1
+ sed 's|1|22|g'
22
+ result=
+ echo '`xxx`' without export
`xxx` without export
+ echo the result is '""'
the result is ""
+ echo '`xxx`' with export
`xxx` with export
++ echo 1
++ sed 's|1|22|g'
+ export result=22
+ result=22
+ echo the result is '"22"'
the result is "22"
+ echo '$(xxx)' without export
$(xxx) without export
+ result=
+ echo the result is '""'
the result is ""
+ echo '$(xxx)' with export
$(xxx) with export
+ export result=
+ result=
+ echo the result is '""'
the result is ""

标签: bashsedcygwin

解决方案


推荐阅读