Bash 脚本已损坏

Bash 脚本已损坏

我制作了一个 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标志可以进行就地编辑。

相关内容