Linux Cygwin中的Bash正在创建具有未知字符的文件夹

Linux Cygwin中的Bash正在创建具有未知字符的文件夹,linux,bash,cygwin,Linux,Bash,Cygwin,我很困惑。我有一个linux备份脚本,我以前使用linux作为我的主操作系统时使用过。现在我已经移动到windows,我想在cygwin下继续使用它。我已经谈过了,但我看到了一个特殊的问题 正如您将在下面的代码中看到的,基本上我创建了一个文件夹结构/device/backups/machinename/。我对其进行了推广,因此它通过hostname确定机器名。如果文件夹结构不存在,它将创建它。我看到的是,该脚本通常可以工作,但它偶尔喜欢创建一个重复的机器名文件夹,后面有一个奇怪的方形字符。此字符

我很困惑。我有一个linux备份脚本,我以前使用linux作为我的主操作系统时使用过。现在我已经移动到windows,我想在cygwin下继续使用它。我已经谈过了,但我看到了一个特殊的问题

正如您将在下面的代码中看到的,基本上我创建了一个文件夹结构/device/backups/machinename/。我对其进行了推广,因此它通过
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”。很抱歉我也将编辑原始问题。