操作系统

当前位置:金沙棋牌 > 操作系统 > Crontab问题总结,ubuntu中实现定时弹窗的提醒脚本

Crontab问题总结,ubuntu中实现定时弹窗的提醒脚本

来源:http://www.logblo.com 作者:金沙棋牌 时间:2019-11-09 02:57

 

2、进行编写定时任务内容,内容如下

这样就实现了

设置了一个crontab
30 0 * * * cd /home/work/user/huangbx/research/getfeature/data/current; sh resample.sh &>/dev/null
$sh resample.sh是可以运行的
$head -5 resample.sh
##对事实数据进行采样
set -x
g_date=`date -d "3 days ago " +%Y%m%d`
可是放到crontab里面就无法运行了。
从网上了解到一般crontab无法运行的问题都是由环境变量在crontab中不一定可识别引起的。可是resample.sh中并没有涉及环境变量的使用。
经过多番尝试,终于发现是代码的第一行的中文注释引起的问题,添加上#!/bin/sh后就可以运行了。
总结了一下:
crontab中必须十分注意环境变量的使用
#!/bin/sh并不是必须,只是当没有sha-bang的时候,也不要在第一行有"#"后带的中文注释!!
最好当然是加上sha-bang啦 #!/bin/sh
2008-11-3补充:
之前没有特别注意环境变量引起的crontab失败,今天果然就遇到了。
问题描述:cron了某sh文件,里面执行多个操作,既调用了外部的shell脚本,也调用了外部的python脚本。从运行日志看,发现部分脚本被调用,而部分python脚本没有被调用。没有被调用的均是python脚本,而且均使用了MySQLdb模块(第三方模块)。
该脚本在平时直接使用sh命令均可以正常执行。
出错信息:
Traceback (most recent call last):
File "areafile.py", line 2, in <module>
    import MySQLdb
File "build/bdist.linux-x86_64/egg/MySQLdb/__init__.py", line 19, in <module>
File "build/bdist.linux-x86_64/egg/_mysql.py", line 7, in <module>
File "build/bdist.linux-x86_64/egg/_mysql.py", line 6, in __bootstrap__
ImportError: libmysqlclient.so.15: cannot open shared object file: No such file or directory
MySQLdb需要调用mysql这个库,可是系统并不知道你的mysql安装在哪里 : (
问题解决:
在总控的shell脚本中添加一句话
export LD_LIBRARY_PATH=/home/work/local/mysql5/lib/mysql
(也就是来自~/.bash_profile中的LD_LIBRARY_PATH字段)后程序终于可以在crontab中正常启动。
解释:
1) ~/.bash_profile && ~/.bashrc
用户登陆Linux操作系统的时候,"/etc/profile", "~/.bash_profile"等配置文件会被自动执行。执行过程是这样的:登陆Linux系统时,首先启动"/etc/profile",然后启动用户目录下的"~/.bash_profile",如果"~/.bash_login"和"~/.profile"文件存在的时候也会在执行"~/.bash_profile"后被依次调用。
下面看看"~/.bash_profile"文件里面有什么东西
$cat ~/.bash_profile
# .bash_profile
# Get the aliases and functions
if [金沙棋牌, -f ~/.bashrc ]; then
        . ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin:/home/work/local/python/lib/python2.5/site-packages/django/bin/:$HOME/bin:/home/work/local/mysql5/bin/;
LD_LIBRARY_PATH=/home/work/local/mysql5/lib/mysql
alias py='/home/work/local/python/bin/python'
export PATH LD_LIBRARY_PATH
unset USERNAME
可以看到~/.bash_profile文件先调用~/.bashrc,然后再把PATH和LD_LIBRARY_PATH加载。
.bash_profile和.bashrc的差别
/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.
并从/etc/profile.d目录的设置文件中搜集shell的设置.
/etc/bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.
~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该
文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件.
~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时及每次打开新的shell时,该
该文件被读取.
~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件.
/etc/profile是全局性的功能,其中设置的变量作用于所有用户,~/.bash_profile中设置的变量能继承/etc/profile中的变量并作用于用户。
~/.bash_profile 是交互式、login 方式进入 bash 运行的
~/.bashrc 是交互式 non-login 方式进入 bash 运行的
通常二者设置大致相同,所以通常前者会调用后者。( )
可是在运行crontab的时候,是non_login方式调用程序的,此时~/.bash_profile并不会被提前调用。所以,crontab的运行环境相对于login方式进入bash运行的环境来说小得多。如果程序涉及~/.bash_profile使用的环境变量,那么,部分在login方式可以正常运行的程序在crontab下就无法运行。
在我的程序中,系统无法识别MySQLdb,于是解决方案就是在总控的shell脚本中添加这样一句:
export LD_LIBRARY_PATH=/home/work/local/mysql5/lib/mysql
更加推荐的解决方案:
在cron中加入
LD_LIBRARY_PATH=/home/work/local/mysql5/lib/mysql
这样cron中所有使用mysql的东东都可以顺利运行了 : ) 而且这样可以使得操作更加清晰。
终极推荐解决方案:
30 12 * * * source ~/.bashrc && cd /home/work/mydir && ./myproj
2) LD_LIBRARY_PATH
Linux运行时有一套共享库(*.so)。共享库的寻找和加载是通过/lib/ld.so (RunTime Shared Library Loader)完成的。ld.so在标准路径(/lib, /usr/lib)下寻找共享库。可是如果第三方库并非安装在标准路径下,程序运行的时候就会出现无法找到库的错误,类似于下面这个报错
ld.so.1: curl: fatal: libgcc_s.so.1: open failed: No such file or directory
通过设置环境变量LD_LIBRARY_PATH可以让ld.so寻找非标准路径的共享库。LD_LIBRARY_PATH中可以设置多个路径,路径之间通过冒号":"分割。LD_LIBRARY_PATH中的路径先于标准路径的查找。
在~/.bash_profile中添加如下代码(比如把mysql的so文件添加进LD_LIBRARY_PATH)
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/work/local/mysql5/lib/mysql
export LD_LIBRARY_PATH
由于~/.bash_profile在用户登陆时会加载(而且仅加载)一次,然后ld.so就会在标准路径和LD_LIBRARY_PATH中自动寻找和加载共享库。
LD_LIBRARY_PATH的缺点:(参考
"For security reasons, LD_LIBRARY_PATH is ignored at runtime for executables that have their setuid or setgid bit set. This severely limits the usefulness of LD_LIBRARY_PATH." ... .... ....."LD_LIBRARY_PATH is one of those insidious things that once it gets set globally for a user, things tend to happen which cause people to rely on it being set. Eventually when LD_LIBRARY_PATH needs to be changed or removed, mass breakage will occur!" ... ... ......"Nowadays you specify the run-time path for an executable at link stage with the -R (or sometimes -rpath) flag to ld. There's also LD_RUN_PATH which is an environment variable which acts to ld just like specifying -R. Before all this you had only -L, which applied not only during compile-time, but during run time as well. There was no way to say “use this directory during compile time” but “use this other directory at run time”. There were some rather spectacular failure modes that one could get in to because of this. "
文中同时给出了如何合理使用LD_LIBRARY_PATH:(虽然没有完全看懂,还是贴一下,期待不久的将来能看懂)
      1) Never ever set LD_LIBRARY_PATH globally.
            If you must ship binaries that use shared libraries and want to allow your clients to install the program outside a 'standard' location, do one of the following:
            Ship your binaries as .o files, and as part of the install process relink them with the correct installation library path.
             Ship executables with a very long “dummy” run-time library path, and as part of the install process use a binary editor to substitute the correct install library path in the executable.
        2) If you are forced to set LD_LIBRARY_PATH, do so only as part of a wrapper.
       3). Remove the link-time aspect of LD_LIBRARY_PATH.....It would be much cleaner if LD_LIBRARY_PATH only had influence at run-time. If necessary, invent some other environment variable for the job (LD_LINK_PATH).
3) ld.so.conf
除了设置LD_LIBRARY_PATH外,还可以设置/etc/ld.so.conf。然后运行ldconfig生成ld.so.cache。ld.so查找公共库的时候也会从ld.so.cache中查找。
不过
"Some OS's (e.g. Linux) have a configurable loader. You can configure what run-time paths to look in by modifying /etc/ld.so.conf. This is almost as bad a LD_LIBRARY_PATH! Install scripts should never modify this file! This file should contain only the standard library locations as shipped with the OS. "
LD_LIBRARY_PATH的runtime Linker详细行为可以参考

我们先不讨论原因,这里,我们就可以看到为什么很多脚本在crontab中编辑后不可以运行了。因为crontab的任务环境就没有定义那么多的环境变量,我们在交互式的环境下写的脚本中用到了这些没有的环境变量,当然可以通过,但是放到crontab下就不行了。

1、在所需用户下(crontab -e 创建定时任务

notify-send ["该休息一下啦"] "喝水!伸懒腰!动一动!"

crontab如果不注意的话早晚会出问题,而且这种问题一旦出一次,就会永远记得,因为这种问题很折腾人。
                                                                                                          ——某前辈

然后我们编辑一个crontab,如下:

5、将定时任务 chmod 755 权限

把这个脚本加入到home目录的.bashrc中,每次登陆就能启动了

 

  1. 定义好一些环境参数,并在crontab里面先source生效,再执行主程序脚本

  2. 直接把脚本中的环境变量改为绝对路径。

具体路径,env查看

while :
do 
 sleep 3600
 echo time past
 notify-send ["该休息一下啦"] "喝水!伸懒腰!动一动!"
done

大家都知道crontab是个好东东,可以定时执行一些任务,帮助你监控系统状况,帮助你每天重复的做一些机械的事情。但是crontab有一个坏毛病,就是它总是不会缺省的从用户profile文件中读取环境变量参数,经常导致在手工执行某个脚本时是成功的,但是到crontab中试图让它定期执行时就是会出错
原先我用一个很傻的办法,就是在脚本中直接指定所有的环境变量参数,每次写脚本都要写好多好多PATH啦,LD_LIBRARY_PATH之类的环境变量参数
后来发现其实可以直接在脚本里先执行一下用户的profile文件,就OK了
如果是Linux环境下的脚本,脚本的头上用缺省的#!/bin/sh就可以了,如果是Solaris环境下的脚本,脚本头上用#!/bin/ksh
然后第一个部分先写这些:
###################
. /etc/profile
. ~/.bash_profile
##################
这样,crontab在执行脚本的时候,就能够读到用户的环境变量参数啦。。。一点儿小技巧而已 ^_^
附:
如果你是在cron里提交的,请注意:
不要假定c r o n知道所需要的特殊环境,它其实并不知道。所以你要保证在s h e l l脚本中提供所有必要的路径和环境变量,除了一些自动设置的全局变量。
如果c r o n不能运行相应的脚本,用户将会收到一个邮件说明其中的原因。

很多时候我们会遇见这种情况,我们千辛万苦写了一个脚本,经过测试,一切正常,然后放到了crontab里面执行,结果,不管怎么配置,就是执行不正常。

crontab命令本身是不带环境变量的,shell脚本是它执行一个文件,在里面写上只是在shell脚本里带上了环境变量,

好了,终于完成了ubuntu中弹窗提醒脚本了,本文提供三种方法供大家参考借鉴,不知道大家都学会了没有,希望这篇文章的内容对大家能有所帮助,如果有疑问大家可以留言交流。

转自:

* * * * * env > /home/crontab.out

将日志追加到 log中

金沙棋牌 1

那么这些环境变量居然差那么多,为什么呢?因为系统的cron deamon会自动设置可构成最小环境的环境变量。

用crontab执行后的进程是由crontab发起的,所有得在crontab里加上环境变量才起作用

在/etc/crontab 中加入了

 1 XDG_SESSION_ID=3
 2 SHELL=/bin/sh
 3 USER=root
 4 PATH=/usr/bin:/bin
 5 PWD=/root
 6 LANG=zh_CN.UTF-8
 7 SHLVL=1
 8 HOME=/root
 9 LOGNAME=root
10 XDG_RUNTIME_DIR=/run/user/0
11 _=/usr/bin/env

在定时任务前加环境变量是因为

总结

结果发现环境问题,居然是这个异常的元凶。

金沙棋牌 2

crontab脚本

 

0 * * * * ./etc/profile; /home/tomcat/restar_jslave.sh >> con_jenkins_crontab.log 2>&1 &

上面的脚本,使用了 notify-send 命令用于在桌面上弹出气泡提示,使用了 zenity 命令用于显示图形窗口。
自己用的话,上面的脚本可以写得更简单一点,因为错误检测没必要做。但是如果要给不太懂的人用的话,我这脚本里的错误检测及处理则会就显得有点力不从心了。

解决方案可以有两种:

或者 定时任务的shell脚本中增加 source /etc/profile 若 无效

crontab -e

我们先在我们的服务器上执行env命令,出现如下:

4、crontab -l 查看已有的定时任务

也用命令编辑了

 

3、保存定时任务

* * * * * root notify-send ["该休息一下啦"] "喝水!伸懒腰!动一动!"

 

解决方法:在conn_jenkins脚本中,添加java的绝对路径(xx/xx/bin)

一、cron命令实现定时弹窗

 1 XDG_VTNR=1
 2 XDG_SESSION_ID=1
 3 HOSTNAME=bogon
 4 IMSETTINGS_INTEGRATE_DESKTOP=yes
 5 GPG_AGENT_INFO=/run/user/0/keyring/gpg:0:1
 6 VTE_VERSION=3802
 7 TERM=xterm
 8 SHELL=/bin/bash
 9 XDG_MENU_PREFIX=gnome-
10 HISTSIZE=1000
11 GJS_DEBUG_OUTPUT=stderr
12 WINDOWID=37748743
13 GJS_DEBUG_TOPICS=JS ERROR;JS LOG
14 IMSETTINGS_MODULE=IBus
15 QT_GRAPHICSSYSTEM_CHECKED=1
16 USER=root
17 SSH_AUTH_SOCK=/run/user/0/keyring/ssh
18 USERNAME=root
19 SESSION_MANAGER=local/unix:@/tmp/.ICE-unix/1672,unix/unix:/tmp/.ICE-unix/1672
20 PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin
21 MAIL=/var/spool/mail/root
22 DESKTOP_SESSION=gnome
23 QT_IM_MODULE=ibus
24 PWD=/root
25 XMODIFIERS=@im=ibus
26 LANG=zh_CN.UTF-8
27 GDM_LANG=zh_CN.UTF-8
28 KDEDIRS=/usr
29 GDMSESSION=gnome
30 SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
31 HISTCONTROL=ignoredups
32 HOME=/root
33 XDG_SEAT=seat0
34 SHLVL=2
35 GNOME_DESKTOP_SESSION_ID=this-is-deprecated
36 XDG_SESSION_DESKTOP=gnome
37 LOGNAME=root
38 DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-VQpgyslPbO,guid=0b7c6ec0e15a92dd89a8eaf654f84153
39 LESSOPEN=||/usr/bin/lesspipe.sh %s
40 WINDOWPATH=1
41 XDG_RUNTIME_DIR=/run/user/0
42 DISPLAY=:0
43 XDG_CURRENT_DESKTOP=GNOME
44 XAUTHORITY=/run/gdm/auth-for-root-A4DlSi/database
45 _=/usr/bin/env

遇到的问题:

下面是脚本:

 

在执行定时任务时,提示java commond not find

三、利用zenity和notify-send实现

然后我们在/home/crontab.out文件中,看看里面的内容。令人奇怪的是,我们发现的里面的信息只有

0 * * * *  /home/tomcat/restar_jslave.sh >> con_jenkins_crontab.log 2>&1 &

简单的弹窗效果

二、shell脚本无限循环实现

终于在一个介绍crontab用法的博客终于找到我的crontab脚本不执行的原因了:没有设置环境变量!

首先是上网查了ubuntu中的弹窗命令,发现notify-send这个命令就能满足要求了

您可能感兴趣的文章:

  • mysql自动化安装脚本(ubuntu and centos64)
  • ubuntu系统中nginx启动脚本
  • Shell脚本实现自动检测修改最快的Ubuntu软件源
  • Ubuntu、Linux Mint一键安装Chrome浏览器的Shell脚本分享
  • 用Shell脚本快速搭建Ubuntu下的Nodejs开发环境
  • 获取服务器信息的Shell脚本分享(ubuntu、centos测试通过)
  • Ubuntu下定时提交代码到SVN服务器的Shell脚本分享
  • Ubuntu Server下MySql数据库备份脚本代码
  • Ubuntu服务器配置apache2.4的限速功能shell脚本分享
  • Ubuntu 14.04设置开机启动脚本的方法
server cron start

想到的是cron命令,google了很多教程,都没有成功

HOME=/
SHELL=/bin/bash
0 * * * * notify-send ["该休息一下啦"] "喝水!伸懒腰!动一动!"

弹窗效果

在crontab文件中定义多个调度任务时,需要特别注环境变量的设置,因为我们手动执行某个任务时,是在当前shell环境下进行的,程序当然能找到环境变量,而系统自动执行任务调度时,是不会加载任何环境变量的,因此,就需要在crontab文件中指定任务运行所需的所有环境变量

还是没有成功

同时也启动了cron服务

弹窗效果有了,然后应该是一个定时弹窗的功能

#!/bin/bash
alartTime=100
while (($alartTime))
do
if (($alartTime != 100)) # 如果不是 100,则说明不是初次运行,则弹出下面的提示
then
notify-send $alartTime"分钟已到,请重新设定!"
zenity --info --text "时间到,请重新设定!"
fi
alartTime=$(zenity --entry --title "定时提醒" --text "输入提醒时间(分钟, 将忽略小数)")
alartTime=${alartTime%.*} # 忽略输入的小数点后面的数字,如 4.6 识别为 4
if (($alartTime > 60)) # 不能超过最大值
then
zenity --info --text "必须小于60分钟,退出"
break
fi
notify-send "成功设定"$alartTime"分钟,开始计时"
sleep $((alartTime*60))
done

本文由金沙棋牌发布于操作系统,转载请注明出处:Crontab问题总结,ubuntu中实现定时弹窗的提醒脚本

关键词:

上一篇:服务目前已停止

下一篇:没有了