Chỉ chạy tập lệnh ngay lần khởi động đầu tiên


12

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:


14

Không. Nhưng bạn có thể muốn đặt tập lệnh của mình vào /etc/init.d/scriptvà tự xóa nó:

#!/bin/bash

echo "Bump! I'm your first-boot script."

# Delete me
rm $0

Xin lưu ý, $0là 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
Andrejs Cainikovs

4
$ 0 KHÔNG phải là bash cụ thể và nó đã được hỗ trợ lâu hơn bash 3.x đã xuất hiện (và nó được hỗ trợ trong Bourne, Korn, zsh và những người khác). Điểm gắn bó là $ 0 có chứa thông số đường dẫn đầy đủ hoặc tương đối hay không. Đây là một liên kết đến một cách đáng tin cậy để có được đường dẫn đầy đủ nếu bạn cần: stackoverflow.com/questions/4774054/ mẹo
Jim Dennis

7

Tạo một tệp theo dõi khi tập lệnh chạy. Nếu tập tin đã tồn tại, thoát khỏi tập lệnh.


3
Mặc dù thoạt nhìn có vẻ không được như vậy, đây có thể là một giải pháp tốt hơn so với việc xóa tập lệnh vì nó vẫn có khả năng kích hoạt lại nó, nếu bạn muốn.
msanford

7

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.shhã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

Điều này không nhất thiết phải làm việc với sysmtemd. Tôi cần thêm một giấc ngủ 20 để đảm bảo đó là lần chạy script cuối cùng.
mrossi

Nếu bạn đặt tên là /etc/rc.local/99-firstboot.sh thì nó sẽ chạy sau cùng.
JohnDavid

3

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.shvà (cứng) liên kết nó với một cái gì đó như thế tstthì chạy ./tstsẽ 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 $PATHtậ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/firstbootvà 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


0

Bạn có thể sao lưu RC.local hiện tại sang RC.local.bak

Sau đó, bạn có thể có những thứ bạn muốn làm trong RC.local và cuối cùng chỉ cần mv /etc/rc.loca.bak /etc/rc.local.


0

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-initcho 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 databên dưới Advanced datails. Nếu bạn đặt cloud-initscript ở đó, 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-initcó 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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.