我制作了一个 bash 脚本来创建一些简单的 macOS ISO 映像,它们最初都可以工作。现在,由于某种原因,我的 echo 命令都不起作用,但是,奇怪的是,如果我在 Mac OS 的终端中手动键入命令或使用重写的命令运行脚本,它会工作得很好。我使用的文件编辑器是微软的Visual Studio Code。
工作命令结果
### Creating OS X Yosemite ISO ###
非工作命令的结果
/Users/will/Desktop/yosemite.sh: line 3: echo -e ### Creating OS X Yosemite ISO ###\n: command not found
下面我将工作命令放在非工作命令(被注释掉的命令)下方,它们看起来相同。当然只有最下面的那个有效。就好像某个地方有一个无效字符。现在,如果我有时间,我会从头开始写出整个内容,但这完全没有成效。
#echo -e "### Creating OS X Yosemite ISO ###\n"
echo -e "### Creating OS X Yosemite ISO ###\n"
知道这是怎么回事吗?
完整剧本
#!/bin/bash
clear
echo -e "### Creating OS X Yosemite ISO ###\n"
#echo -e "### Creating OS X Yosemite ISO ###\n"
sleep 30
echo -n "Checking if application exists... "
if [ -d "/Applications/Install OS X Yosemite.app" ]
then
echo "Application is already downloaded and ready to continue."
sleep 4
break
elif [ -f "$script_dir\Yosemite.tar.gz" ]
then
echo -n "Extracting archive to Applications directory... "
tar -xzvf "$script_dir\Yosemite.tar.gz" --strip-components=1 -C "/Applications/"
echo "Done"
sleep 4
else
echo -e "Yosemite can not be found. \n\nPlease download the application or place the archive in the root directory with this script."
sleep 4
exit
fi
echo -n "Doing clean-up... "
rm -f /tmp/Yosemite.dmg /tmp/Yosemite.sparseimage
hdiutil detach /Volumes/install_app
hdiutil detach /Volumes/install_build
echo -n "Attaching 'OS X Install ESD' disk image... "
hdiutil attach /Applications/Install\ OS\ X\ Yosemite.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app
echo "Done"
echo -n "Converting disk image to sparse image... "
hdiutil convert /Volumes/install_app/BaseSystem.dmg -format UDSP -o /tmp/Yosemite
echo "Done"
echo -n "Attaching 'OS X Base System' image... "
hdiutil attach /tmp/Yosemite.sparseimage -noverify -nobrowse -mountpoint /Volumes/install_build
echo "Done"
echo -n "Removing redundancies... "
rm /Volumes/install_build/System/Installation/Packages
echo "Done"
echo -n "Copying files from 'OS X Install ESD' > 'OS X Base System'... "
cp -rp /Volumes/install_app/Packages /Volumes/install_build/System/Installation/
cp -rp /Volumes/install_app/BaseSystem.chunklist /Volumes/install_build
cp -rp /Volumes/install_app/BaseSystem.dmg /Volumes/install_build
echo "Done"
echo -n "Renaming volume... "
diskutil rename /Volumes/install_build Install\ OS\ X\ Yosemite
bless --folder "/Volumes/Install OS X Yosemite/System/Library/CoreServices" --label "Install OS X Yosemite"
echo "Done"
echo -n "Unmounting volumes... "
hdiutil detach /Volumes/install_app
hdiutil detach /Volumes/Install\ OS\ X\ Yosemite
echo "Done"
echo -n "Converting Sparse image to ISO file... "
hdiutil convert /tmp/Yosemite.sparseimage -format UDTO -o /tmp/Yosemite.cdr
echo "Done"
echo -n "Renaming file extension and moving ISO to current user's desktop... "
mv /tmp/Yosemite.cdr ~/Desktop/Yosemite.iso
echo "Done"
echo -n "Removing left-over files... "
rm -f /tmp/Yosemite.dmg /tmp/Yosemite.sparseimage
echo "Done"
sleep 4
echo -e "\n### Successfully created 'Install OS X Yosemite.iso' ###"
更新1
没有-A
参数,cat
所以我用以下命令打开了手册man cat
:
-b Number the non-blank output lines, starting at 1.
-e Display non-printing characters (see the -v option), and display a dollar sign (`$') at the end of each line.
-n Number the output lines, starting at 1.
-s Squeeze multiple adjacent empty lines, causing the output to be single spaced.
-t Display non-printing characters (see the -v option), and display tab characters as `^I'.
-u Disable output buffering.
-v Display non-printing characters so they are visible. Control characters print as `^X' for control-X; the delete character (octal 0177) prints as `^?'. Non-ASCII characters (with the high bit set) are printed as `M-' (for meta)
followed by the character for the low 7 bits.
的结果cat -etv /Users/musicroom/Desktop/yosemite.sh
#!/bin/bash$
clear$
echo -e "### Creating OS X Yosemite ISO ###\n"$
#echo -e "### Creating OS X Yosemite ISO ###\n"$
sleep 30$
echo -n "Checking if application exists... "$
if [ -d "/Applications/Install OS X Yosemite.app" ] $
then$
echo "Application is already downloaded and ready to continue."$
sleep 4$
break$
elif [ -f "$script_dir\Yosemite.tar.gz" ]$
then$
echo -n "Extracting archive to Applications directory... "$
tar -xzvf "$script_dir\Yosemite.tar.gz" --strip-components=1 -C "/Applications/"$
echo "Done"$
sleep 4$
else$
echo -e "Yosemite can not be found. \n\nPlease download the application or place the archive in the root directory with this script."$
sleep 4$
exit$
fi^I^I^I$
$
echo -n "Doing clean-up... "$
rm -f /tmp/Yosemite.dmg /tmp/Yosemite.sparseimage$
hdiutil detach /Volumes/install_app$
hdiutil detach /Volumes/install_build$
echo -n "Attaching 'OS X Install ESD' disk image... "$
hdiutil attach /Applications/Install\ OS\ X\ Yosemite.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app$
echo "Done"$
echo -n "Converting disk image to sparse image... "$
hdiutil convert /Volumes/install_app/BaseSystem.dmg -format UDSP -o /tmp/Yosemite$
echo "Done"$
echo -n "Attaching 'OS X Base System' image... "$
hdiutil attach /tmp/Yosemite.sparseimage -noverify -nobrowse -mountpoint /Volumes/install_build$
echo "Done"$
echo -n "Removing redundancies... "$
rm /Volumes/install_build/System/Installation/Packages$
echo "Done"$
echo -n "Copying files from 'OS X Install ESD' > 'OS X Base System'... "$
cp -rp /Volumes/install_app/Packages /Volumes/install_build/System/Installation/$
cp -rp /Volumes/install_app/BaseSystem.chunklist /Volumes/install_build$
cp -rp /Volumes/install_app/BaseSystem.dmg /Volumes/install_build$
echo "Done"$
echo -n "Renaming volume... "$
diskutil rename /Volumes/install_build Install\ OS\ X\ Yosemite$
bless --folder "/Volumes/Install OS X Yosemite/System/Library/CoreServices" --label "Install OS X Yosemite"$
echo "Done"$
echo -n "Unmounting volumes... "$
hdiutil detach /Volumes/install_app$
hdiutil detach /Volumes/Install\ OS\ X\ Yosemite$
echo "Done"$
echo -n "Converting Sparse image to ISO file... "$
hdiutil convert /tmp/Yosemite.sparseimage -format UDTO -o /tmp/Yosemite.cdr$
echo "Done"$
echo -n "Renaming file extension and moving ISO to current user's desktop... "$
mv /tmp/Yosemite.cdr ~/Desktop/Yosemite.iso$
echo "Done"$
echo -n "Removing left-over files... "$
rm -f /tmp/Yosemite.dmg /tmp/Yosemite.sparseimage$
echo "Done"$
sleep 4$
echo -e "\n### Successfully created 'Install OS X Yosemite.iso' ###"
更新2
我已经运行了 dos2unix 并将脚本转换为新文件,运行了脚本,遗憾的是结果相同。
更新3
的结果hexdump -C /Users/musicroom/Desktop/yosemite.sh | head
00000000 23 21 2f 62 69 6e 2f 62 61 73 68 0a 63 6c 65 61 |#!/bin/bash.clea|
00000010 72 0a 65 63 68 6f c2 a0 2d 65 c2 a0 22 23 23 23 |r.echo..-e.."###|
00000020 c2 a0 43 72 65 61 74 69 6e 67 c2 a0 4f 53 c2 a0 |..Creating..OS..|
00000030 58 c2 a0 59 6f 73 65 6d 69 74 65 c2 a0 49 53 4f |X..Yosemite..ISO|
00000040 c2 a0 23 23 23 5c 6e 22 0a 23 65 63 68 6f 20 2d |..###\n".#echo -|
00000050 65 20 22 23 23 23 20 43 72 65 61 74 69 6e 67 20 |e "### Creating |
00000060 4f 53 20 58 20 59 6f 73 65 6d 69 74 65 20 49 53 |OS X Yosemite IS|
00000070 4f 20 23 23 23 5c 6e 22 0a 73 6c 65 65 70 20 33 |O ###\n".sleep 3|
00000080 30 0a 65 63 68 6f 20 2d 6e 20 22 43 68 65 63 6b |0.echo -n "Check|
00000090 69 6e 67 20 69 66 20 61 70 70 6c 69 63 61 74 69 |ing if applicati|
更新 4(已修复)
当使用十六进制转储进行检查时,我可以明确地看到两个 echo 命令之间的差异。我现在的问题是,如何批量删除它们?
nano 和 vi CLI 编辑器不会显示任何奇怪的字符,我什至安装了 Atom 编辑器,以防 Visual Studio Code 运行时不会突然显示任何内容。
在 Atom 和 Visual Studio Code 中,这两个编辑器都设置为 UTF-8 编码。然而,直到我将编码设置为DOS (CP 347)
我开始在命令中看到奇怪的字符时,我才知道这会导致问题。这是启用编码的脚本DOS (CP 347)
:
#!/bin/bash
clear
echo -e "### Creating OS X Yosemite ISO ###\n"
#echo -e "### Creating OS X Yosemite ISO ###\n"
sleep 30
echo -n "Checking if application exists... "
if [ -d "/Applications/Install OS X Yosemite.app" ]
then
echo "Application is already downloaded and ready to continue."
sleep 4
break
elif [ -f "$script_dir\Yosemite.tar.gz" ]
then
echo -n "Extracting archive to Applications directory... "
tar -xzvf "$script_dir\Yosemite.tar.gz" --strip-components=1 -C "/Applications/"
echo "Done"
sleep 4
else
echo -e "Yosemite can not be found. \n\nPlease download the application or place the archive in the root directory with this script."
sleep 4
exit
fi
echo -n "Doing clean-up... "
rm -f /tmp/Yosemite.dmg /tmp/Yosemite.sparseimage
hdiutil detach /Volumes/install_app
hdiutil detach /Volumes/install_build
echo -n "Attaching 'OS X Install ESD' disk image... "
hdiutil attach /Applications/Install\ OS\ X\ Yosemite.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app
echo "Done"
echo -n "Converting disk image to sparse image... "
hdiutil convert /Volumes/install_app/BaseSystem.dmg -format UDSP -o /tmp/Yosemite
echo "Done"
echo -n "Attaching 'OS X Base System' image... "
hdiutil attach /tmp/Yosemite.sparseimage -noverify -nobrowse -mountpoint /Volumes/install_build
echo "Done"
echo -n "Removing redundancies... "
rm /Volumes/install_build/System/Installation/Packages
echo "Done"
echo -n "Copying files from 'OS X Install ESD' > 'OS X Base System'... "
cp -rp /Volumes/install_app/Packages /Volumes/install_build/System/Installation/
cp -rp /Volumes/install_app/BaseSystem.chunklist /Volumes/install_build
cp -rp /Volumes/install_app/BaseSystem.dmg /Volumes/install_build
echo "Done"
echo -n "Renaming volume... "
diskutil rename /Volumes/install_build Install\ OS\ X\ Yosemite
bless --folder "/Volumes/Install OS X Yosemite/System/Library/CoreServices" --label "Install OS X Yosemite"
echo "Done"
echo -n "Unmounting volumes... "
hdiutil detach /Volumes/install_app
hdiutil detach /Volumes/Install\ OS\ X\ Yosemite
echo "Done"
echo -n "Converting Sparse image to ISO file... "
hdiutil convert /tmp/Yosemite.sparseimage -format UDTO -o /tmp/Yosemite.cdr
echo "Done"
echo -n "Renaming file extension and moving ISO to current user's desktop... "
mv /tmp/Yosemite.cdr ~/Desktop/Yosemite.iso
echo "Done"
echo -n "Removing left-over files... "
rm -f /tmp/Yosemite.dmg /tmp/Yosemite.sparseimage
echo "Done"
sleep 4
echo -e "\n### Successfully created 'Install OS X Yosemite.iso' ###"
dos2unix 是否应该解决这个问题,因为当我使用 运行它时没有任何运气dos2unix -n /Users/will/Desktop/yosemite.sh output.sh
?
我使用了 Visual Studio Code 中的“查找和替换”功能,并将所有内容替换┬á
为空格,保存它,将编码更改回 UFT-8,重新运行脚本,它就可以工作了。
答案1
以下行为例:
00000010 72 0a 65 63 68 6f c2 a0 2d 65 c2 a0 22 23 23 23 |r.echo..-e.."###|
What are these characters -- ^ ^ ^ ^
a0 是高位设置的空格 20 ?? C2 的高位设置为 42 ?
摆脱那些奇怪的东西。使用vi
更新1:创建一个新文件
选择(使用鼠标),然后使用 CTRL-C(或在 mac 上 cmd-C)复制此网页上问题中的原始脚本并创建一个新文件:
$ cat > fixscript.sh
现在将内容粘贴到cat
并使用 CTRL-D 终止输入。这是hd fixedscript.sh
上面同一行的输出。
00000010 72 0a 65 63 68 6f 20 2d 65 20 22 23 23 23 20 43 |r.echo -e "### C|
答案2
在 vim 中编辑二进制文件的标准答案是使用xxd
将文件转换为十六进制,进行更改,然后使用xxd -r
将其转换回二进制。
然而,为此我可能会使用 perl。
perl -p0e 's/\x{c2}\x{a0}/ /g' input_file > output_file
当您有信心时,还有一个-i
标志可以进行就地编辑。