Linux Cygwin中的Bash正在创建具有未知字符的文件夹
我很困惑。我有一个linux备份脚本,我以前使用linux作为我的主操作系统时使用过。现在我已经移动到windows,我想在cygwin下继续使用它。我已经谈过了,但我看到了一个特殊的问题 正如您将在下面的代码中看到的,基本上我创建了一个文件夹结构/device/backups/machinename/。我对其进行了推广,因此它通过Linux Cygwin中的Bash正在创建具有未知字符的文件夹,linux,bash,cygwin,Linux,Bash,Cygwin,我很困惑。我有一个linux备份脚本,我以前使用linux作为我的主操作系统时使用过。现在我已经移动到windows,我想在cygwin下继续使用它。我已经谈过了,但我看到了一个特殊的问题 正如您将在下面的代码中看到的,基本上我创建了一个文件夹结构/device/backups/machinename/。我对其进行了推广,因此它通过hostname确定机器名。如果文件夹结构不存在,它将创建它。我看到的是,该脚本通常可以工作,但它偶尔喜欢创建一个重复的机器名文件夹,后面有一个奇怪的方形字符。此字符
hostname
确定机器名。如果文件夹结构不存在,它将创建它。我看到的是,该脚本通常可以工作,但它偶尔喜欢创建一个重复的机器名文件夹,后面有一个奇怪的方形字符。此字符在cygwin中显示为问号。那么,我会看到:/device/backups/machinename和/device/backups/machinename?同时Cygwin似乎混淆了这两个文件夹,有时备份到第一个,有时备份到第二个。它也不会始终如一地创建此文件夹,但如果我让它在一周内每天运行,它就会显示出来
还请注意,它设计为按文件夹运行,文件夹名称作为参数传入。以FolderName.0.tar.gz、FolderName.1.tar.gz等格式保存一周的存档
我现在将尝试通过硬编码机器名来解决这个问题,但我真的很有兴趣找出问题所在。以下是我的脚本的来源:
#!/bin/bash
#Backup Docs
for FOLDER in $@
do
# Location of folder to be backed up
FOLDERLOCATION="/home/sean"
# Mount point of the backup device
DEVICE="/cygdrive/f"
# Hostname of the machine being backed up
HOSTNAME=`hostname`
# NOTE: when I originally posted this question, the above line read:
# HOSTNAME=`txtmsgbreakup`
# which doesn't make any sense. I failed at changing the hard-coded solution back
# to the original command that produces the string "txtmsgbreakup" (my system's name)
BACKUPFOLDER="$FOLDERLOCATION/$FOLDER/"
BACKUPDEST="$DEVICE/backups/$HOSTNAME/$FOLDER/"
# Check to see if device is mounted
if [ -d $DEVICE ]
then
# Create directory if necessary
if [ ! -d $BACKUPDEST ]; then
mkdir -p $BACKUPDEST
fi
# Capture before time for logging
before=$(date +%s)
# First, tar up the old into file named after day of week
DOW=`date +%w`
FILENAME="$DEVICE/backups/$HOSTNAME/$FOLDER.$(( ($DOW+6)%7 )).tar.gz"
if [ -e $FILENAME ]; then
rm $FILENAME
fi
tar -czPf $FILENAME $BACKUPDEST
# Now perform the backup
rsync -a --del --ignore-errors $BACKUPFOLDER $BACKUPDEST
after=$(date +%s)
# Calculate how long the backup took
elapsed_seconds=$(($after-$before))
es=$((elapsed_seconds % 60))
em=$(( (elapsed_seconds / 60) % 60 ))
eh=$((elapsed_seconds / 3600 ))
# Write it all to the system log
echo "$(date) - $BACKUPFOLDER backed up. Elapsed time: $(printf '%02d:%02d:%02d' $eh $em $es)" >> /var/log/backup
else
#External is not mounted if this branch is executed, log this.
echo "$(date) - $BACKUPFOLDER not backed up: Backup device not mounted." >> /var/log/backup
fi
done
您应该删除
HOSTNAME=
txtmsgbreakup
如果要放置字符串,请尝试:HOSTNAME=“txtmsgbreakup”或者如果需要动态主机名,则变量$HOSTNAME已经存在于您的环境中
根据我对问题的理解,您可能希望使用字符串“txtmsgbreakup”定义主机名,但当您将其放在backticks`中时,您要求运行一个不存在的命令
此外,在shell变量中使用更多引号以避免出现问题(某一天)我应该补充:备份设备是一个外部HDD格式的NTFS。这是启动脚本的一部分吗?当脚本启动时,设备是否仍在装载?(不太可能,但只是一个想法)。您可以使用
ls-d${BACKUPFOLDER}*|od--format=m
显示奇数球字符的内容。祝你好运。ls-b
也应该显示这个奇怪的角色是什么。由于您使用的是Windows,我猜这是回车(\r),因为Windows倾向于使用\r\n终止行。如果使用Windows编辑器编辑了脚本,则需要从中清除\r。另一种可能是txtmsgbreakup
生成Windows风格的输出,在这种情况下,您需要在使用它之前清理它的输出。ls | cat-A
应该足以向您展示有趣的角色是什么ls
通常将不可打印的字符呈现为?
,但如果其输出被重定向,则会按字面显示它们cat-A
将ASCII CR字符转换为^M
(选择一个绝对非随机的示例)。犯了一个愚蠢的错误,将脚本更改回其原始形式。我通过硬编码HOSTNAME=“txtmsgbreakup”而不是HOSTNAME=HOSTNAME
解决了这个问题。我把它改回了HOSTNAME=txtmsgbreakup
,这是无效的。脚本从来没有这样运行过,这只是我发布的内容中的一个错误,所以这不是问题。是的,我是个白痴。正如您所建议的,我已将脚本更改为硬代码“txtmsgbreakup”,但在本例中将其更改回原始版本。我将引号改为记号,但忘记将字符串改为“hostname”。因此,该行实际上是主机名
,而不是txtmsgbreakup
,它在我的特定机器上计算为“txtmsgbreakup”。很抱歉我也将编辑原始问题。