Tôi thực sự đánh giá cao nỗ lực đưa vào câu trả lời của Dennis Williamson . Tôi muốn chấp nhận nó như là câu trả lời cho câu hỏi này, tuy nhiên nó thanh lịch và đơn giản:
- Cuối cùng tôi cảm thấy rằng nó đòi hỏi quá nhiều bước để thiết lập.
- Nó đòi hỏi quyền truy cập root.
Tôi nghĩ rằng giải pháp của anh ấy sẽ tuyệt vời như một tính năng vượt trội của bản phân phối Linux.
Điều đó đang được nói, tôi đã viết kịch bản của riêng mình để thực hiện ít nhiều điều tương tự như giải pháp của Dennis. Nó không yêu cầu bất kỳ bước thiết lập bổ sung nào và nó không yêu cầu quyền truy cập root.
#!/bin/bash
if [[ $# -eq 0 ]]; then
echo "Schedules a command to be run after the next reboot."
echo "Usage: $(basename $0) <command>"
echo " $(basename $0) -p <path> <command>"
echo " $(basename $0) -r <command>"
else
REMOVE=0
COMMAND=${!#}
SCRIPTPATH=$PATH
while getopts ":r:p:" optionName; do
case "$optionName" in
r) REMOVE=1; COMMAND=$OPTARG;;
p) SCRIPTPATH=$OPTARG;;
esac
done
SCRIPT="${HOME}/.$(basename $0)_$(echo $COMMAND | sed 's/[^a-zA-Z0-9_]/_/g')"
if [[ ! -f $SCRIPT ]]; then
echo "PATH=$SCRIPTPATH" >> $SCRIPT
echo "cd $(pwd)" >> $SCRIPT
echo "logger -t $(basename $0) -p local3.info \"COMMAND=$COMMAND ; USER=\$(whoami) ($(logname)) ; PWD=$(pwd) ; PATH=\$PATH\"" >> $SCRIPT
echo "$COMMAND | logger -t $(basename $0) -p local3.info" >> $SCRIPT
echo "$0 -r \"$(echo $COMMAND | sed 's/\"/\\\"/g')\"" >> $SCRIPT
chmod +x $SCRIPT
fi
CRONTAB="${HOME}/.$(basename $0)_temp_crontab_$RANDOM"
ENTRY="@reboot $SCRIPT"
echo "$(crontab -l 2>/dev/null)" | grep -v "$ENTRY" | grep -v "^# DO NOT EDIT THIS FILE - edit the master and reinstall.$" | grep -v "^# ([^ ]* installed on [^)]*)$" | grep -v "^# (Cron version [^$]*\$[^$]*\$)$" > $CRONTAB
if [[ $REMOVE -eq 0 ]]; then
echo "$ENTRY" >> $CRONTAB
fi
crontab $CRONTAB
rm $CRONTAB
if [[ $REMOVE -ne 0 ]]; then
rm $SCRIPT
fi
fi
Lưu tập lệnh này (ví dụ runonce
:) chmod +x
, và chạy:
$ runonce foo
$ runonce "echo \"I'm up. I swear I'll never email you again.\" | mail -s \"Server's Up\" $(whoami)"
Trong trường hợp lỗi chính tả, bạn có thể xóa lệnh khỏi hàng đợi runonce với cờ -r:
$ runonce fop
$ runonce -r fop
$ runonce foo
Sử dụng sudo hoạt động theo cách bạn mong đợi nó hoạt động. Hữu ích để bắt đầu một máy chủ chỉ một lần sau lần khởi động lại tiếp theo.
myuser@myhost:/home/myuser$ sudo runonce foo
myuser@myhost:/home/myuser$ sudo crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/root/.runonce_temp_crontab_10478 installed on Wed Jun 9 16:56:00 2010)
# (Cron version V5.0 -- $Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp $)
@reboot /root/.runonce_foo
myuser@myhost:/home/myuser$ sudo cat /root/.runonce_foo
PATH=/usr/sbin:/bin:/usr/bin:/sbin
cd /home/myuser
foo
/home/myuser/bin/runonce -r "foo"
Một số lưu ý:
- Kịch bản này sao chép môi trường (PATH, thư mục làm việc, người dùng) mà nó được gọi.
- Về cơ bản, nó được thiết kế để trì hoãn việc thực thi một lệnh vì nó sẽ được thực thi "ngay tại đây, ngay bây giờ" cho đến sau chuỗi khởi động tiếp theo.