最近在利用 crontab 构建自动备份时,遇到了一个问题。我的脚本中包含了用于服务器用户切换使用的 ssh 命令。当我登录到服务器上时,脚本执行正常;当我没有登录到服务器上时,脚本执行失败,错误提示是:

Could not create directory '/home/server/.ssh'

在登录到服务器上后,可以看到 “/home/server/.ssh” 路径是存在的,也是正常的。

各个用户间的 ssh key 也已经生成好了,在登录到服务器上后,手动调用主脚本,可以正常的完成脚本的执行流程,但是由 crontab 自动调用时,仍然无法正常工作。

在网上查找相关信息的时候,在 stackoverflow 上有人问类似的问题,但是并没有人给出了可行的解答。 rsync code will run, but not in cron. 原文链接

资料查找没有找到可行的结果,只能自己想办法了。因为登录和不登录结果不一样,首先怀疑是不是登录导致环境变量有所改变。为了确认这一点,我在主脚本中加入了 echo 命令,来打印 SSH 使用到的环境变量。具体的环境变量包含以下内容:

     DISPLAY               The DISPLAY variable indicates the location of the X11 server.  It is automatically set by ssh to point to a value of the form
``hostname:n'', where ``hostname'' indicates the host where the shell runs, and `n' is an integer >= 1. ssh uses this special value to
forward X11 connections over the secure channel. The user should normally not set DISPLAY explicitly, as that will render the X11 con-
nection insecure (and will require the user to manually copy any required authorization cookies). HOME Set to the path of the user's home directory. LOGNAME Synonym for USER; set for compatibility with systems that use this variable. MAIL Set to the path of the user's mailbox. PATH Set to the default PATH, as specified when compiling ssh. SSH_ASKPASS If ssh needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. If ssh does not have a
terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS and open an X11
window to read the passphrase. This is particularly useful when calling ssh from a .xsession or related script. (Note that on some
machines it may be necessary to redirect the input from /dev/null to make this work.) SSH_AUTH_SOCK Identifies the path of a UNIX-domain socket used to communicate with the agent. SSH_CONNECTION Identifies the client and server ends of the connection. The variable contains four space-separated values: client IP address, client
port number, server IP address, and server port number. SSH_ORIGINAL_COMMAND This variable contains the original command line if a forced command is executed. It can be used to extract the original arguments. SSH_TTY This is set to the name of the tty (path to the device) associated with the current shell or command. If the current session has no
tty, this variable is not set. TZ This variable is set to indicate the present time zone if it was set when the daemon was started (i.e. the daemon passes the value on
to new connections). USER Set to the name of the user logging in.

通过打印上述环境变量,发现登录前和登录后打印出的结果完全一致,但是没有登录的话,自动执行脚本就会提示“Could not create directory ‘/home/server/.ssh’”

这个问题还是很奇怪,不知道为什么会这样。为了去解决这个问题,我尝试在本地部署一个自动执行脚本,用于自动登录到服务器上调用服务器自动备份脚本,来实现自动备份。当自动登录部署完成后,发现了一个新的问题:当我登录在服务器上时,自动登录可以执行成功;当我没有登录到服务器上时,自动登录无法执行成功。在没有登录上服务器时,用户目录和登录上之后不一样??

为了验证这个想法,执行一下 mount 命令,结果如下:

/dev/sda1 on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/cgroup type tmpfs (rw)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
none on /run/user type tmpfs (rw,noexec,nosuid,nodev,size=104857600,mode=0755)
none on /sys/fs/pstore type pstore (rw)
systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd)
/home/server/.Private on /home/server type ecryptfs (ecryptfs_check_dev_ruid,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_unlink_sigs,ecryptfs_sig=a1f33ec3321f0ef9,ecryptfs_fnek_sig=705c22000a171cfe)

从 mount 的结果上看,用户目录是被 mount 上的。再次进行测试,在 crontab 里通过自动脚本执行 mount 命令。对比发现,在自动执行时,用户目录是没有被挂载的。那么,这就是问题原因了:

在没有登录到服务器上时,用户目录没有被挂载。因为没有被挂载,所以用户目录的权限不对!!

为了验证这个想法,再次登录到服务器上,手动将用户目录进行卸载

sudo umount /home/server

卸载掉用户目录后,再次进入目录中进行查看

server@gitlabserver:~$ ls -a
. .. Access-Your-Private-Data.desktop
.bash_history .ecryptfs .kde
.Private README.txt .viminfo

我们发现,用户目录到内容变了。

因为服务器用户目录是经过了 “ecryptfs” 加密,所以在没有登录和登录后不一样。知道了这一点,解决自动登录到方法也就变得简单了:将用户目录中的 .ssh 目录拷贝到卸载后的用户目录中。

经过上述的拷贝,自动执行的脚本终于可以顺利执行了,问题圆满解决。

我在 stackoverflow 上回答了这个问题。自己记录一下,看看是不是能帮到别人: stackoverflow

欢迎转载,转载请保留: 
转自Elta 的博客:http://www.eltaera.com//2017/01/18/crontab_ssh.html

Crontab could not create directory .ssh的更多相关文章

  1. cygwin Could not create directory '/home/Administrator/.ssh'

    在cygwin下运行: ssh-keygen -C "634772208@qq.com" -t rsa 时,出现如下错误: cygwin Could not create dire ...

  2. org.apache.hadoop.hdfs.server.namenode.SafeModeException: Cannot create directory /user/hive/warehouse/page_view. Name node is in safe mode

    FAILED: Error in metadata: MetaException(message:Got exception: org.apache.hadoop.ipc.RemoteExceptio ...

  3. vsftp关于"550 create directory operation failed"问题解决

    前提: 昨天晚上配置好了vsftp, 但登陆后,除了浏览,什么也干不了.(如新建文件/文件夹, 删除文件, 重命名等都不可操作) 都是弹出 "550 create directory ope ...

  4. [hadoop]Cannot create directory /mdrill/tablelist/fact_seller_all_d. Name node is in safe mode.

    在执行mdrill创建表的时候报如下异常(蓝色部分为关键): [mdrill@hadoop1101 bin]$ ./bluewhale mdrill create ./create.sql higo ...

  5. 550 Create directory operation failed

    往Linux系统中上传文件时候,我们经常会使用FTP连接Linux,也经常会使用mkdir命令来创建目录.最近发现用mkdir创建目录时提示550 Create directory operation ...

  6. Linux虚拟主机通过FTP软件创建目录时提示550 Create Directory Operation Failed

    更新时间:2017-06-07 13:26:11   分享: 问题描述 通过FTP软件连接Linux虚拟主机,在尝试创建新目录时,服务器返回错误提示:550 Create Directory Oper ...

  7. 非root用户启动redis容器报错mkdir: cannot create directory '/bitnami/redis': Permission denied

    问题:使用docker启动容器时,报错如下 zh@debian:~/testPath$ docker-compose up redis Starting testpath_redis_1 ... do ...

  8. HTTP Status 500 - Unable to create directory

    分析原因: 例如:java web项目 上传图片创建文件夹cd /data/apps/static-web/sjk/driver/attachment/编号/文件名称.jpg 在创建文件目录 /dat ...

  9. Hadoop "Cannot create directory .Name node is in safe mode."解决方案

    转载自:http://www.waitig.com/hadoop-name-node-is-in-safe-mode.html 在使用Hadoop建立文件的时候,出现“Cannot create di ...

随机推荐

  1. Init.rc分析(刘举奎)

    http://www.360doc.com/content/14/0926/20/13253385_412582822.shtml

  2. 获取一个gridcontrol的数据行数

    ((DataTable)gc_excel.DataSource).Rows.Count;

  3. 什么是deferred对象

    $.when().done().then()的用法  http://www.cnblogs.com/tiancai/p/5817996.html jQuery的开发速度很快,几乎每半年一个大版本,每两 ...

  4. CSS3样式linear-gradient的使用(切角效果)

    linear-gradient linear-gradient是CSS3中新增的样式,主要用于颜色的渐变效果.MDN地址 linear-gradient在不同内核下使用方式不同,详细内容可参考w3cp ...

  5. iOS开发——自定义进度圆环

    1.在DrawCircle.h文件中 提供了接口,在使用的时候,可以设定圆心.半径.角度.圆环的宽度.圆环的背景底色.圆环的进度条颜色,当然后面三个有自定义的值. // //  DrawCircle. ...

  6. KERMIT,XMODEM,YMODEM,ZMODEM传输协议小结(转)

    源:KERMIT,XMODEM,YMODEM,ZMODEM传输协议小结 Kermit协议 报文格式: 1.MARK,起始标记START_CHAR,为 0x01(CTRIL-A): 2.LEN,报文剩余 ...

  7. Oracle物化视图的用法与总结

    物化视图(material view)是什么? 物化视图是包括一个查询结果的数据库对象,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表. 物化视图存储基于远程表的数据,也可以称为快照(类 ...

  8. iOS开发——点击图片全屏显示

    点击图片,全屏显示,然后再点击屏幕一下,返回. 没啥难的,直接上代码: // //  ViewController.m //  Demo-hehe // //  Created by yyt on 1 ...

  9. Hibernate 中对象关系映射(ObjectRelationMapping)

    1.什么是对象关系映射? 解析:对象-关系映射(Object Relational Mapping,简称ORM,对象关系映射)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说, ...

  10. Tsinsen-A1489 抽奖 【数学期望】

    乔明达太神,其实已经题解非常清楚了,我再推一遍吧. 题目意思相当于有n个盒子,无差别投m次球,每个盒子的得分为每个盒子里的球的个数. 第一问: 假设这个球放在了第i个盒子里,那么 ∆ans = (mi ...