Linux crontab 使用的环境变量如何与用户变量完全相同 ? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AaronLee
V2EX    问与答

Linux crontab 使用的环境变量如何与用户变量完全相同 ?

  •  
  •   AaronLee 2023-08-22 06:39:41 +08:00 1394 次点击
    这是一个创建于 832 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题

    我使用 next-terminal 作为管理 VPS 的工具,因为网络环境不好经常导致 next-terminal 的 webssh 断开,使用 screen 作为 webssh 断开快速恢复的方式,配置 crontab 重启后创建一个 screen ,配置.bashrc作为每次 ssh 链接恢复 screen ,问题,使用 crontab 创建和我手动创建 screen 差异巨大,crontab 创建 screen 基本无法使用,手动创建 screen 可以使用。

    自己查找

    通过 Google 搜索得知要在/etc/screenrc,添加shell -$SHELL ,可以使用用户环境变量,手动创建 screen 可以,但 crontab 创建不行,研究发现 crontab 环境变量与用户使用的环境变量差异巨大。希望 crontab 环境变量与用户变量相同。

    代码

    crontab 配置

    @reboot sleep 10 && /usr/bin/screen -d -l -m 

    说明:用户为 www ,机器启动 10 秒后执行/usr/bin/screen -d -l -m,创建 screenrc ,已废弃

    @reboot sleep 10 && /home/www/.web-ssh.sh 

    说明:机器启动 10 秒后执行 /home/www/.web-ssh.sh
    /home/www/.web-ssh.sh 脚本

    #!/bin/bash source /home/www/.bash_profile /usr/bin/screen -d -l -m 

    用于获取环境变量的脚本

    #!/bin/bash source /home/www/.bash_profile env >>/tmp/env.log 2>&1 

    手动执行获取环境变量脚本

    SHELL=/bin/bash FLYCTL_INSTALL=/home/www/.fly PWD=/home/www LOGNAME=www XDG_SESSION_TYPE=tty MOTD_SHOWN=pam HOME=/home/www LANG=zh_CN.UTF-8 LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36: SSH_COnNECTION=IP 34370 IP XDG_SESSION_CLASS=user TERM=xterm-256color USER=www SHLVL=3 XDG_SESSION_ID=13 XDG_RUNTIME_DIR=/run/user/1000 SSH_CLIENT=IP 34370 22 XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop PATH=/home/www/.fly/bin:/home/www/.fly/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus SSH_TTY=/dev/pts/0 _=/usr/bin/env 

    crontab 执行获取环境变量脚本

    SHELL=/bin/sh FLYCTL_INSTALL=/home/www/.fly PWD=/home/www LOGNAME=www HOME=/home/www LANG=zh_CN.UTF-8 SHLVL=1 PATH=/home/www/.fly/bin:/usr/bin:/bin _=/usr/bin/env 

    .bashrc 尾部添加代码,用于每次 SSH 连接恢复 screen

    screen -r 

    想法

    要解决问题

    1.crontab 使用的变量与我 SSH 登录上去使用的变量完全相同

    2.修改.bashrc ,机器重启后第一次登录执行/usr/bin/screen -d -l -m,再执行screen -r,之后每次 SSH 连接只执行screen -r,除非机器重启。(超出我能力)

    额外

    @reboot sleep 10 && /usr/bin/screen -S next-terminal 

    不会执行

    6 条回复    2024-03-03 15:36:46 +08:00
    huntagain2008
        1
    huntagain2008  
       2023-08-22 09:24:49 +08:00
    我不懂,问了 poe.com 的 GPT-4:

    从你的描述中看,你希望在使用 `crontab` 启动 `screen` 时,能够使用和用户登录时相同的环境变量。这个问题的根源是 `crontab` 在执行任务时,使用的是一个非常基础的环境变量集,而不是用户的完整环境变量。

    有一种解决方案是在 `crontab` 中直接加载用户的环境变量。你可以在 `crontab` 的命令中使用 `source` 命令,在执行任务之前先加载用户的 `.bashrc` 或 `.bash_profile` 文件。这样,`screen` 就能在和用户登录时相同的环境中运行了。

    以下是一个例子,你可以在 `crontab` 文件中添加这样一条命令:

    ```bash
    @reboot /bin/bash -c "source /home/yourusername/.bashrc; /usr/bin/screen -dmS yourscreenname"
    ```

    在这个命令中,`/home/yourusername/.bashrc` 应该替换为你的 `.bashrc` 文件的实际路径,`yourscreenname` 应该替换为你想要的 `screen` 名称。

    这个命令首先启动一个 `bash` shell ,然后在这个 shell 中加载 `.bashrc` 文件,最后在这个环境中启动 `screen`。

    请注意,这个解决方案可能并不适用于所有情况,因为有些环境变量可能只在特定的交互式 shell 中有效。在这种情况下,你可能需要手动在 `crontab` 命令中设置这些环境变量。
    AaronLee
        2
    AaronLee  
    OP
       2023-08-22 13:40:52 +08:00
    @huntagain2008 感谢回复,按照你的方法``` @reboot /bin/bash -c "source /home/www/.bashrc; /usr/bin/screen -dmS next-terminal" ```配置,还是不行,我得到 source 新建窗口还是灰色(正常使用蓝色),没有 TAB 键自动填充,无法删除输入的字符,无法复制粘贴。目前解决的方法时机器重启后利用 next-terminal 的快捷指令功能手动执行```/usr/bin/screen -d -l -m```,再在.bashrc 添加 screen -r 。这样只要不重启,就可以登录 SSH 自动恢复 source 。
    AaronLee
        3
    AaronLee  
    OP
       2023-08-23 06:46:31 +08:00
    还是决定将变量强制写入脚本,这样开机就能执行。首先通过 ```env``` 获取环境变量,接着将变量写入脚本,这是现在的脚本代码:
    ```
    #!/bin/bash

    export SHELL=/bin/bash
    export FLYCTL_INSTALL=/home/www/.fly
    export PWD=/home/www
    export LOGNAME=www
    export XDG_SESSION_TYPE=tty
    export MOTD_SHOWN=pam
    export HOME=/home/www
    export LANG=zh_CN.UTF-8
    export XDG_SESSION_CLASS=user
    export TERM=xterm-256color
    export USER=www
    export SHLVL=1
    export XDG_SESSION_ID=20
    export XDG_RUNTIME_DIR=/run/user/1000
    export XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
    export PATH=/home/www/.fly/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin
    export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
    export SSH_TTY=/dev/pts/0
    export _=/usr/bin/env

    env >>/tmp/env.log 2>&1

    /usr/bin/screen -dmS next-terminal

    ```
    AaronLee
        4
    AaronLee  
    OP
       2023-08-23 10:23:07 +08:00
    还有种方法,首先.bashrc 尾部添加以下内容
    ```
    # 每次 SSH 进入机器都会将环境变量写入.next-terminal.env
    env > ~/.next-terminal.env
    # 恢复 screen
    screen -r
    ```
    脚本修改为
    ```
    #!/bin/bash

    source ~/.next-terminal.env

    env >>/tmp/env.log 2>&1

    /usr/bin/screen -dmS next-terminal
    ```
    julyclyde
        5
    julyclyde  
       2023-08-23 22:22:43 +08:00
    这是典型的没搞清楚环境变量是“运行”出来的,并且只对产生环境变量的进程及其子进程有效
    误以为存在一个神圣入口可以直接给“用户”施加环境变量
    AaronLee
        6
    AaronLee  
    OP
       2024-03-03 15:36:46 +08:00
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1015 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 23:31 PVG 07:31 LAX 15:31 JFK 18:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86