Có một cách thành ngữ trong Ubuntu để chạy tập lệnh chỉ khi lần đầu tiên máy được khởi động? (EC2).
Có một cách thành ngữ trong Ubuntu để chạy tập lệnh chỉ khi lần đầu tiên máy được khởi động? (EC2).
Câu trả lời:
Không. Nhưng bạn có thể muốn đặt tập lệnh của mình vào /etc/init.d/script
và tự xóa nó:
#!/bin/bash
echo "Bump! I'm your first-boot script."
# Delete me
rm $0
Kết hợp hai câu trả lời đầu tiên Giả sử bạn đặt tên cho tập lệnh của mình, /usr/local/bin/firstboot.sh
hãy đặt nó ở cuối /etc/rc.local
(tập lệnh này chạy trên mỗi lần khởi động) các tập lệnh diễn ra như thế này
#! / bin / bash CỜ = "/ var / log / Firstboot.log" nếu [ ! -f $ CỜ]; sau đó # Ở đây câu khởi tạo của bạn echo "Đây là lần khởi động đầu tiên" # dòng tiếp theo tạo một tệp trống để nó không chạy lần khởi động tiếp theo chạm $ FLAG khác tiếng vang "Không làm gì cả" fi
Tôi ngạc nhiên với kết quả mà tôi thấy khi tìm kiếm một hook "boot" đầu tiên được xác định rõ và được hỗ trợ. Có vẻ như đám đông Red Hat / Fedora / CentOS đã đóng đinh trong hơn một thập kỷ. Tương đương Ubuntu gần nhất có vẻ là OEM-config-Firstboot .
Ý tưởng chỉ đơn giản là thực hiện một rm $0
ý chí sẽ làm việc. Nhưng, về mặt kỹ thuật có một số ngữ nghĩa thú vị liên quan. Không giống như hầu hết các trình thông dịch tập lệnh khác trong Unix, tập lệnh shell được đọc và xử lý một dòng / câu lệnh tại một thời điểm. Nếu bạn hủy liên kết ( rm
) tệp ra từ bên dưới thì phiên bản shell đó đang xử lý tập lệnh đó hiện đang hoạt động với một tệp ẩn danh (bất kỳ tệp nào mở nhưng không được liên kết).
Hãy xem xét một tập tin như thế này:
#!/bin/bash
rm $0
echo "I've removed myself: $0"
ls -l $0
cat <<COMMENTARY
This is a test.
I'm still here, because the "here" doc is being fed to 'cat'
via the anonymous file through the open file descriptor.
But I cannot be re-exec'd
COMMENTARY
exec $0
Nếu bạn lưu nó vào một cái gì đó giống như rmself.sh
và (cứng) liên kết nó với một cái gì đó như thế tst
thì chạy ./tst
sẽ hiển thị một cái gì đó như thế này như đầu ra:
$ ./tst
I've removed myself: ./tst
ls: ./tst: No such file or directory
This is a test.
I'm still here, because the "here" doc is being fed to 'cat'
via the anonymous file through the open file descriptor.
But I cannot be re-exec'd
./tst: line 11: /home/jimd/bin/tst: No such file or directory
./tst: line 11: exec: /home/jimd/bin/tst: cannot execute: No such file or directory
Bây giờ có một số trường hợp góc kỳ lạ có thể liên quan đến symlink và các trường hợp trong đó tập lệnh được gọi dưới dạng tên trần (buộc shell phải tìm kiếm $PATH
tập lệnh.
Nhưng có vẻ như bash
(ít nhất là trong phiên bản 3.2) $0
đi trước đường dẫn nếu nó tìm kiếm đường dẫn và nếu không thì đặt $ 0 thành bất kỳ đường dẫn tương đối hoặc tuyệt đối nào được sử dụng để gọi tập lệnh. Nó dường như không thực hiện bất kỳ đường dẫn tương đối chuẩn hóa hoặc độ phân giải cũng như liên kết tượng trưng.
Có lẽ "Firstboot" sạch nhất cho Ubuntu sẽ là tạo một gói nhỏ (.deb) chứa tập lệnh được đặt vào /etc/init.d/firstboot
và tập lệnh sau khi cài đặt sử dụng update-rc.d
để liên kết nó với runlevel 1 ( /etc/rc1.d
) (sử dụng lệnh như update-rc.d firstboot defaults
:)). .. và sau đó có dòng cuối cùng thực hiện hủy kích hoạt hoặc xóa bằng cách sử dụng một cái gì đó như:update-rc.d firstboot disable
Đây là một liên kết đến bản cập nhật Debian-rc.d HOWTO
Câu hỏi là về việc chạy một kịch bản trong lần khởi động đầu tiên của EC2. Bạn có thể sử dụng cloud-init
cho mục đích này.
Khi khởi chạy một thể hiện EC2 mới, bạn có một tùy chọn để xác định User data
bên dưới Advanced datails
. Nếu bạn đặt cloud-init
script ở đó, nó sẽ chỉ được thực thi ở lần khởi động đầu tiên.
Ví dụ: bạn có thể đặt như sau User data
:
#cloud-config
runcmd:
- /usr/bin/command1.sh
- /usr/bin/command2.sh
Đầu ra sẽ được ghi vào /var/log/cloud-init-output.log
Cloud-init
có thể làm nhiều hơn thế này Nó được thiết kế đặc biệt để thực hiện khởi tạo sớm các trường hợp đám mây. Xem các tài liệu ở đây: http://cloudinit.readthedocs.io/en/latest/index.html
$0
là dành riêng cho bash (phiên bản> = 3). Để tương thích, bạn có thể cung cấp tên tệp tập lệnh thay vào đó, làm cho nó ít chung chung hơn:rm /etc/init.d/script