shell cronjob中的sed未解释脚本变量

xxhby3vn  于 2023-03-09  发布在  Shell
关注(0)|答案(1)|浏览(179)

Debian 11 Bullseye中使用“sed”的Bash脚本可以从命令行运行,但不能作为cron运行
嗨,我正在运行Debian GNU/Linux 11 (bullseye) Linux 5.15.84-v8+ #1613 SMP PREEMPT Thu Jan 5 12:03:08 GMT 2023 aarch64 GNU/Linux
在我的设置中,我有两个bash脚本:
一个不同的脚本一天24小时每分钟不停地用JPEG文件填充我的文件夹,这是一个cronjob,运行完美。
当从命令行运行/home/myuser下面的脚本运行完美,并创建一个文件,列出所有JPEG文件在myfolder之间的开始时间和完成时间
例如文件名2023-03-05_1014.jpg
例如,从命令行myfolder/2023-03-05_1014.jpg创建的output.txt

#!/bin/bash
cd /home/myuser/
current_date=$(date +%F)
time_start=2023-03-05_0900
time_finish=2023-03-05_1700

ls myfolder/"$current_date"_*.jpg | sed -n "/myfolder\/$time_start/, /myfolder\/$time_finish/p" > output.txt

以用户myuser(非root)身份作为cronjob运行时
00 22 * * * /home/myuser/create_jpg_list.sh 2>&1
output.txt将列出myfolder中的每个文件,其中列出了从0000到2359的每个JPEG文件。也就是说,sed命令中的变量似乎没有被解释。
例如,对于从cronjob myfolder/2023-03-05_2302.jpg创建的output.txt,该行不应显示在output.txt中,因为它超出了上午9点到下午5点的时间范围
我已经在网上搜索过了,有一些线程,如下面的链接(仅举几例)处理这种情况,但唉https://unix.stackexchange.com/questions/614759/sed-doesnt-work-under-cronhttps://askubuntu.com/questions/524726/not-able-to-run-sed-on-bash-scripthttps://unix.stackexchange.com/questions/662851/why-this-script-doesnt-work-from-cron-while-it-works-when-invoke-from-my-shellhttps://www.linuxquestions.org/questions/linux-newbie-8/sed-not-working-from-cron-706865/
欢迎任何反馈,因为我不知道还能尝试什么。

ukqbszuj

ukqbszuj1#

sed地址的开始/结束条件为“categorical"。也就是说,它是固定的at first match。因此,虽然这对于开始条件可以正常工作,捕获多个匹配项中的第一个,但对于结束条件不起作用,只提供多个匹配项中的第一个。
此外,地址上没有“比较”,因此不能使用1701作为结束条件的规范。
awk是这种细粒度控制的更好选择,同时在某些类型的匹配上提供了更大的灵活性。
下面的脚本包含一个演示模式(无需指定命令行参数),它将演示原始**sed地址匹配和awk**方法的输出,以给予您想要的结果。

逻辑演示脚本:

#!/bin/bash

demo=0 
sel_date=""

while [ $# -gt -0 ]
do
    case $1 in
        --demo )    demo=1 ; shift ;;
        --today )   sel_date=$(date +%F) ; shift ;;
        --date )    sel_date="$2" ; shift ; shift ;;
        --start )   stime="${2}" ; shift ; shift ;;
        --end )     etime="${2}" ; shift ; shift ;;
        --dir )     startdir="${2}" ; shift ; shift ;;
        * ) echo "\n\t Invalid parameter used on command line.  Only valid options: [ --today | --date {yyyy-mm-dd} | --start {hhmm} | --end {hhmm} ]\n Bye!\n" ; exit 1 ; ;;
    esac
done

if [ ${demo} -eq 1  -o  -z "${startdir}" ]
then
    demo=1
    echo " ****  DEMO MODE IN EFFECT  **** "
    startdir="myuser"
fi
echo "${startdir}"

if [ ${demo} -eq 1  -o  -z "${sel_date}" ]
then
    sel_date="2023-03-05"
fi
echo "${sel_date}"

if [ ${demo} -eq 1  -o  -z "${stime}" ]
then
    stime="0900"
fi
echo "${stime}"

if [ ${demo} -eq 1  -o  -z "${etime}" ]
then
    etime="1700"
fi
echo "${etime}"

if [ ${demo} -eq 1 ]
then

    if [ ! -d myuser ]
    then
        mkdir myuser
    fi
    ###
    ###  Create test environment for logic confirmation
    ###
    for mdate in 2023-02-30  2023-03-05  2023-03-08
    do
        echo -e "\t ${mdate} ..."
        for mtime in 0700 0900 1100 1300 1500 1700 1900
        do
            echo -e "\t\t ${mtime} ..."
            for count in 001 005 009
            do
                echo -e "\t\t\t ${count} ..."
                echo "dummy" >"${startdir}/${mdate}_${mtime}_${count}.jpg"
            done
        done
    done
fi

cd `dirname "${startdir}" `

time_start="${sel_date}_${stime}"
time_finish="${sel_date}_${etime}"

ls -1 "${startdir}/${sel_date}_"*.jpg
echo ""

### Method 1 - Inappropriate
ls "${startdir}/${sel_date}_"*.jpg | sed -n "/${startdir}\/${time_start}/, /${startdir}\/${time_finish}/p" | tee output1.txt

wc -l output1.txt

### Method 2 - 
ls "${startdir}/${sel_date}_"*.jpg | 
awk -v pdate="${sel_date}" -v stime="${stime}" -v etime="${etime}" '{
    ### Input format:  'myuser/2023-03-05_0900_001.jpg'
    n=split( $0, line, "/" ) ;
    split( line[n], dat, "_" ) ;
    if( dat[1] == pdate ){
        if( dat[2] >= stime && dat[2] <= etime ){
            print $0 ;
        } ;
    } ;
}' | tee output2.txt
wc -l output2.txt

相关问题