【问题标题】:Bash in Cygwin creating folder with unknown characterCygwin中的Bash创建具有未知字符的文件夹
【发布时间】:2011-12-05 06:57:19
【问题描述】:

我很困惑。我有一个 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

【问题讨论】:

  • 我应该补充一点:备份设备是一个外部 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 这是无效的。脚本从来没有这样运行过,这只是我发布的内容中的一个错误,所以这不是问题。

标签: linux bash cygwin


【解决方案1】:

你应该删除HOSTNAME=txtmsgbreakup

如果您想输入一个字符串,请尝试:HOSTNAME="txtmsgbreakup" 或者如果您想要动态主机名,变量 $HOSTNAME 已经在你的环境。

根据我对您的问题的理解,您希望使用字符串“txtmsgbreakup”定义 HOSTNAME,但是当您将其放在反引号 ` 中时,您要求运行一个不存在的命令。

此外,在你的 shell 变量中使用更多的引号来避免事情被破坏(有一天)

【讨论】:

  • 是的,我是个白痴。按照您的建议,我已将脚本更改为硬编码“txtmsgbreakup”,但在此示例中将其更改回原来的。我将引号更改为刻度,但忘记将字符串更改为“主机名”。所以那行实际上是hostname 而不是txtmsgbreakup,它在我的特定机器上计算为“txtmsgbreakup”。对不起。我也会编辑原始问题。
猜你喜欢
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多