3

我有一个 bash 脚本,用于迁移从配置文件读取的一些 IMAP 邮件帐户。

它适用于单行条目,但是当我有多个帐户时,只有第一个条目有效,其余的由于某种原因删除了用户名的第一个字符。我用来暂停和等待击键的命令也没有暂停。(我可以调试那部分,但如果我不需要,我肯定会支持你!)

我 99% 确定我的问题是我不完全理解的唯一一行:

CREDS=(${VAR// / })

同样值得注意的是密码充满了特殊字符,但没有空格。这是代码:

#! /bin/bash
# Script to help migrate email account contents
# must have accounts all ready set up and using IMAP
# uses hardcoded dovecot master user on host2 too bad host1 is stupid courier

# uses file mailusers.cfg for users and passwords
# one entry per line - format is:
# username@domain.com passwordstring

while read p; do
  VAR=$p
  CREDS=(${VAR// / })
  VARUSER=${CREDS[0]}
  VARPASS=${CREDS[1]}
  OUTPUT="Username: $VARUSER Password: $VARPASS"
  echo $OUTPUT
  imapsync --host1 123.456.789.123 --user1 $VARUSER --password1 $VARPASS --authmech1 PLAIN --host2 999.888.777.123 --user2 $VARUSER*masteruser@mydomain.com --password2 notreallypasswordXD --authmech2 PLAIN --exclude 'Trash|Spam'
  echo "Done!"
  echo
  read -n 1 -s
done < mailusers.cfg

注意:这个脚本不应该在其他用户登录的系统上运行,因为如果他们碰巧运行 ps aux 我相信他们可以看到用户名/密码。有关详细信息,请参阅 imapsync 文档。

4

2 回答 2

3

您缺少用户名的第一个字符的原因与您的 pause 不起作用的原因完全相同:您的 pause ( read -n 1 -p) 从stdin. 但是,stdin已经重定向到数据文件,所以它读取用户名的第一个字符。

您确实需要在扩展中引用变量。养成这样做的习惯。它更安全。

我也不知道替换行的作用:当您展示它时,它看起来像是一个空操作,但我想其中一个空格可能是一个制表符。无论如何,这是不必要的。你可以用这样的 shell 变量来替换所有这些鬼混:

while read -r VARUSER VARPASS ignore_rest_of_line; do
  echo "Username: $VARUSER Password: $VARPASS"
  imapsync --host1 123.456.789.123 --user1 "$VARUSER" \
           --password1 "$VARPASS" --authmech1 PLAIN \
           --host2 999.888.777.123 \
           --user2 "$VARUSER*masteruser@mydomain.com" \
           --password2 notreallypasswordXD \
           --authmech2 PLAIN --exclude 'Trash|Spam'
  echo "Done!"
  echo
  read -n 1 -s < /dev/tty
done < mailusers.cfg
于 2013-09-13T17:35:10.313 回答
0

正如所指出的,您可以将输入重定向read -n 1 -s/dev/tty,但另一种方法是为您的输入文件使用不同的文件描述符:

while read -u 4 p; do
  VAR=$p
  CREDS=(${VAR// / })
  VARUSER=${CREDS[0]}
  VARPASS=${CREDS[1]}
  OUTPUT="Username: $VARUSER Password: $VARPASS"
  echo $OUTPUT
  imapsync --host1 123.456.789.123 --user1 $VARUSER --password1 $VARPASS --authmech1 PLAIN --host2 999.888.777.123 --user2 $VARUSER*masteruser@mydomain.com --password2 notreallypasswordXD --authmech2 PLAIN --exclude 'Trash|Spam'
  echo "Done!"
  echo
  read -n 1 -s
done 4< mailusers.cfg

我认为这条线

  CREDS=(${VAR// / })

没有什么不同

  CREDS=($VAR)

而且也更好

  read -ra CREDS <<< "$VAR"

因为它可以防止路径名扩展。

于 2013-09-13T17:50:34.617 回答