Chciałbym wiedzieć, jak utworzyć powitalny dla Ubuntu Maverick z komunikatami rozruchowymi wyświetlanymi podczas uruchamiania, a także pasek postępu i obracające się logo.
Lub, jeśli to możliwe, jak edytować panel powitalny, który ma już obracające się logo i pasek postępu, i dodawać do niego komunikaty rozruchowe.
To jest temat, który chciałbym edytować:
i chciałbym coś takiego:
lub to, co dokładnie chcę utworzyć:
udało mi się znaleźć tę stronę internetową, która zawiera wiele przydatnych informacji, ale mam trudności z jej zrozumieniem. nie robiłem wcześniej żadnego skryptu!
Utwórz własny ekran powitalny z przewijanymi komunikatami rozruchowymi
i to jest kolejna strona internetowa, która może pomóc w tworzeniu skryptów
to jest skrypt dla paska postępu w widoku powitalnym:
#----------------------------------------- Progress Bar --------------------------------
progress_box.image = Image("progress_box.png");
progress_box.sprite = Sprite(progress_box.image);
progress_box.x = Window.GetX() + Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
progress_box.y = Window.GetY() + Window.GetHeight() * 0.65 - progress_box.image.GetHeight() / 2;
progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);
progress_bar.original_image = Image("progress_bar.png");
progress_bar.sprite = Sprite();
progress_bar.x = Window.GetX() + Window.GetWidth() / 2 - progress_bar.original_image.GetWidth() / 2;
progress_bar.y = Window.GetY() + Window.GetHeight() * 0.65 - progress_box.image.GetHeight() / 2 + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);
fun progress_callback (duration, progress)
{
if (progress_bar.image.GetWidth () != Math.Int (progress_bar.original_image.GetWidth () * progress))
{
# add the * 3 to multiply the speed of the progress bar by 3
progress_bar.image = progress_bar.original_image.Scale(progress_bar.original_image.GetWidth(progress_bar.original_image) * progress * 3, progress_bar.original_image.GetHeight());
progress_bar.sprite.SetImage (progress_bar.image);
}
}
Plymouth.SetBootProgressFunction(progress_callback);
OK, więc przeprowadziłem znacznie więcej poszukiwań i mogłem dowiedzieć się nieco więcej o Plymouth.
to są strony, które uznałem za przydatne. Przewodnik tematyczny w Plymouth Istnieją cztery części tego artykułu, które musisz przeczytać, aby uzyskać sedno tego, co robimy. (Porównywałem ich skrypt ze skryptem dla mojego powitania, aby zrozumieć, co to jest, zalecam zrobienie tego, jeśli ktoś ma pójść w moje ślady.) Skrypt Plymouth Ok, ten link ma 2 strony, które musiał przejść przez nich, aby zrozumieć, co robić . Okazało się, że chodziło o to samo, co ja, czyli o przekierowanie komunikatów rozruchowych do Plymouth splash, gdzie mam już obracające się logo, tło, pasek postępu.
Musiałem więc edytować /lib/lsb/init-functions
plik i sprawić, aby wysyłał komunikaty o błędzie rozruchu / sukcesie itp. Do Plymouth poprzez dodanie tego akapitu
# SEND MESSAGES TO PLYMOUTH
if [ -x /bin/plymouth ] && pidof plymouthd >/dev/null
then
plymouth_send() {
[ "$1" = '-n' ] && { # add a flag '>' for lines that will be extended
shift
/bin/plymouth message --text=">$*" || true
return
}
[ "$1" = '-w' ] && { # add "warning" formatting
shift
/bin/plymouth update --status="warning" || true
/bin/plymouth message --text="$*" || true
/bin/plymouth update --status="normal" || true
return
}
[ "$1" = '-f' ] && { # add "failed" formatting
shift
/bin/plymouth update --status="failed" || true
/bin/plymouth message --text="$*" || true
/bin/plymouth update --status="normal" || true
return
}
/bin/plymouth message --text="$*" || true
}
else
plymouth_send() { :; }
fi
# int log_begin_message (char *message)
log_begin_msg () {
if [ -z "${1:-}" ]; then
return 1
fi
echo -n "$@"
}
Jak również dodawanie
# Only do the fancy stuff if we have an appropriate terminal
# and if /usr is already mounted
if log_use_fancy_output; then
RED=`$TPUT setaf 1`
YELLOW=`$TPUT setaf 3`
NORMAL=`$TPUT op`
else
RED=''
YELLOW=''
NORMAL=''
fi
if [ $1 -eq 0 ]; then
echo "."
plymouth_send "."
elif [ $1 -eq 255 ]; then
/bin/echo -e " ${YELLOW}(warning).${NORMAL}"
plymouth_send -w " (warning)."
else
/bin/echo -e " ${RED}failed!${NORMAL}"
plymouth_send -f " failed!"
fi
log_end_msg_post "$@"
return $retval
}
log_action_msg () {
echo "$@."
plymouth_send "$@."
}
log_action_begin_msg () {
echo -n "$@..."
plymouth_send -n "$@..."
}
log_action_cont_msg () {
echo -n "$@..."
plymouth_send -n "$@..."
}
log_action_end_msg () {
log_action_end_msg_pre "$@"
if [ -z "${2:-}" ]; then
end="."
else
end=" ($2)."
fi
if [ $1 -eq 0 ]; then
echo "done${end}"
plymouth_send "done${end}"
else
if log_use_fancy_output; then
RED=`$TPUT setaf 1`
NORMAL=`$TPUT op`
/bin/echo -e "${RED}failed${end}${NORMAL}"
else
echo "failed${end}"
plymouth_send -f "failed${end}"
fi
fi
log_action_end_msg_post "$@"
}
Do tej pory nie byłem w stanie przekazać wiadomości do Plymouth, ale lepiej zrozumiałem, jak działają skrypty Plymouth!
Nie wiem, co jeszcze mam zrobić, aby działało! mając nadzieję, że ktoś tu może mi pomóc
Och, a oto moja wersja skryptu dla Splasha , nad którym pracuję.
# INT2MIL-Ubuntu-10.10-Eng splashy like theme
Window.GetMaxWidth = fun (){
i = 0;
width = 0;
while (Window.GetWidth(i)){
width = Math.Max(width, Window.GetWidth(i));
i++;
}
return width;
};
Window.GetMaxHeight = fun (){
i = 0;
height = 0;
while (Window.GetHeight(i)){
height = Math.Max(height, Window.GetHeight(i));
i++;
}
return height;
};
anim.imagecount = 100;
anim.target_width = 0.2* 0.46 * Window.GetWidth();
anim.target_height = 0.2* 0.46 * Window.GetWidth();
fun RotatedImage (index){
index = Math.Int(index);
if (!RotatedImageCache[index])
RotatedImageCache[index] = anim.original_image.Rotate((Math.Pi*2*index)/anim.imagecount).Scale(anim.target_width, anim.target_height);
return RotatedImageCache[index];
}
if (Plymouth.GetMode() == "suspend" || Plymouth.GetMode() == "resume") {
background.original_image = ImageNew("suspend.png");
Window.SetBackgroundTopColor(1, 0, 0);
Window.SetBackgroundBottomColor(0, 1, 0);
}
else {
logo.original_image = ImageNew("logo.png");
background.original_image = ImageNew("background.png");
Window.SetBackgroundTopColor(0.234, 0.43, 0.705);
Window.SetBackgroundBottomColor(0.16, 0.25, 0.44);
anim.image= ImageNew("animation.png");
anim.original_image= anim.image.Scale(anim.target_width, anim.target_width);
anim.sprite = SpriteNew();
anim.sprite.SetImage(RotatedImage (0));
anim.sprite.SetX((Window.GetX() + Window.GetWidth() - RotatedImage(0).GetWidth()) / 2);
anim.sprite.SetY(Window.GetY() + Window.GetHeight() * 0.37);
anim.angle = 0;
anim.index = 0;
}
#change reduction size to make logo bigger
ratio = logo.original_image.GetWidth() / logo.original_image.GetHeight();
reduction = 0.4;
logo.image = logo.original_image.Scale(reduction * Window.GetMaxWidth() , reduction / ratio * Window.GetMaxWidth());
logo.sprite = SpriteNew();
logo.sprite.SetImage(logo.image);
logo.opacity_angle = 0;
#change logo location
logo.sprite.SetX((Window.GetX() + Window.GetMaxWidth() - logo.image.GetWidth()) / 2);
logo.sprite.SetY(Window.GetY() + Window.GetHeight() * 0.37);
#background image attributs x,z,y
background.image = background.original_image.Scale(Window.GetMaxWidth() , Window.GetMaxHeight());
background.sprite = SpriteNew();
background.sprite.SetImage(background.image);
background.sprite.SetPosition(Window.GetX(), Window.GetY(), -10);
sprite_prompt = SpriteNew();
fun refresh_callback ()
{
if (status == "normal")
{
#anim.index=speed of rotation
anim.index += 1;
anim.index %= anim.imagecount;
anim.sprite.SetImage(RotatedImage (anim.index));
#anim.sprite.SetOpacity (1);
motif.sprite.SetOpacity(motif.opacity);
}
else
{
anim.sprite.SetOpacity(0);
motif.sprite.SetOpacity(0);
}
}
if (Plymouth.GetMode() != "suspend" && Plymouth.GetMode() != "resume") {
Plymouth.SetRefreshFunction (refresh_callback);
}
#----------------------------------------- Dialog --------------------------------
status = "normal";
fun dialog_setup()
{
local.box;
local.lock;
local.entry;
local.prompt_sprite;
box.image = ImageNew("box.png");
lock.image = ImageNew("lock.png");
entry.image = ImageNew("entry.png");
box.sprite = SpriteNew();
box.sprite.SetImage(box.image);
box.x = Window.GetX() + Window.GetWidth() / 2 - box.image.GetWidth()/2;
box.y = Window.GetY() + Window.GetHeight() / 2 - box.image.GetHeight()/2;
box.z = 10000;
box.sprite.SetPosition(box.x, box.y, box.z);
lock.sprite = SpriteNew();
lock.sprite.SetImage(lock.image);
lock.x = box.x + box.image.GetWidth()/2 - (lock.image.GetWidth() + entry.image.GetWidth()) / 2;
lock.y = box.y + box.image.GetHeight()/2 - lock.image.GetHeight()/2;
lock.z = box.z + 1;
lock.sprite.SetPosition(lock.x, lock.y, lock.z);
entry.sprite = SpriteNew();
entry.sprite.SetImage(entry.image);
entry.x = lock.x + lock.image.GetWidth();
entry.y = box.y + box.image.GetHeight()/2 - entry.image.GetHeight()/2;
entry.z = box.z + 1;
entry.sprite.SetPosition(entry.x, entry.y, entry.z);
prompt_sprite = SpriteNew();
prompt_sprite.SetPosition(box.x, box.y - 20, box.z);
global.dialog.box = box;
global.dialog.lock = lock;
global.dialog.entry = entry;
global.dialog.bullet_image = ImageNew("bullet.png");
global.dialog.prompt_sprite = prompt_sprite;
dialog_opacity (1);
}
fun dialog_opacity(opacity)
{
dialog.box.sprite.SetOpacity(opacity);
dialog.lock.sprite.SetOpacity(opacity);
dialog.entry.sprite.SetOpacity(opacity);
dialog.prompt_sprite.SetOpacity(opacity);
for (index = 0; dialog.bullet[index]; index++)
{
dialog.bullet[index].sprite.SetOpacity(opacity);
}
}
fun display_normal_callback ()
{
global.status = "normal";
if (global.dialog)
dialog_opacity (0);
}
fun display_password_callback (prompt, bullets)
{
global.status = "password";
if (!global.dialog)
dialog_setup();
else
dialog_opacity(1);
motif.sprite.SetOpacity(0);
anim.sprite.SetOpacity(0);
dialog.prompt_sprite.SetImage(Image.Text(prompt, 1.0, 1.0, 1.0));
for (index = 0; dialog.bullet[index] || index < bullets; index++)
{
if (!dialog.bullet[index])
{
dialog.bullet[index].sprite = SpriteNew();
dialog.bullet[index].sprite.SetImage(dialog.bullet_image);
dialog.bullet[index].x = dialog.entry.x + index * dialog.bullet_image.GetWidth();
dialog.bullet[index].y = dialog.entry.y + dialog.entry.image.GetHeight() / 2 - dialog.bullet_image.GetHeight() / 2;
dialog.bullet[index].z = dialog.entry.z + 1;
dialog.bullet[index].sprite.SetPosition(dialog.bullet[index].x, dialog.bullet[index].y, dialog.bullet[index].z);
}
if (index < bullets)
dialog.bullet[index].sprite.SetOpacity(1);
else
dialog.bullet[index].sprite.SetOpacity(0);
}
}
fun display_message_callback (prompt)
{
prompt = Image.Text(prompt,1.0, 1.0, 1.0);
sprite_prompt.SetImage(prompt);
sprite_prompt.SetPosition(Window.GetX() + (Window.GetWidth() - prompt.GetWidth()) / 2, Window.GetY() + Window.GetHeight() * 0.93, 2);
}
/* instantiate dialog at startup, to ensure all icons are loaded in memory before initrd is unmounted, in case /usr isn't mounted yet */
dialog_setup(); dialog_opacity(0);
Plymouth.SetDisplayNormalFunction(display_normal_callback);
Plymouth.SetDisplayPasswordFunction(display_password_callback);
Plymouth.SetMessageFunction(display_message_callback);
#----------------------------------------- Progress Bar --------------------------------
progress_box.image = Image("progress_box.png");
progress_box.sprite = Sprite(progress_box.image);
progress_box.x = Window.GetX() + Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
progress_box.y = Window.GetY() + Window.GetHeight() * 0.65 - progress_box.image.GetHeight() / 2;
progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);
progress_bar.original_image = Image("progress_bar.png");
progress_bar.sprite = Sprite();
progress_bar.x = Window.GetX() + Window.GetWidth() / 2 - progress_bar.original_image.GetWidth() / 2;
progress_bar.y = Window.GetY() + Window.GetHeight() * 0.65 - progress_box.image.GetHeight() / 2 + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);
fun progress_callback (duration, progress)
{
if (progress_bar.image.GetWidth () != Math.Int (progress_bar.original_image.GetWidth () * progress))
{
progress_bar.image = progress_bar.original_image.Scale(progress_bar.original_image.GetWidth(progress_bar.original_image) * progress * 3, progress_bar.original_image.GetHeight());
progress_bar.sprite.SetImage (progress_bar.image);
}
}
Plymouth.SetBootProgressFunction(progress_callback);
#----------------------------------------- Status Update --------------------------------
NUM_SCROLL_LINES = 5;
LINE_WIDTH = 55;
# width of one character
CHAR_WIDTH = 7;
# height of one character
CHAR_HEIGHT = 10;
msg_color = [0.5,0.5,0.5]; # msg_color is array
fun update_status_callback(sta) {
if (sta == "failed") msg_color = [1,0,0];
if (sta == "warning") msg_color = [0.8,0.8,0];
if (sta == "normal") msg_color = [0.5,0.5,0.5];
}
fun StringLength(string) {
index = 0;
str = String(string);
while(str.CharAt(index)) index++;
return index;
}
// Initialising text images and their positions
// 20 is the height (including line spacing) of each line
for (i=0; i < NUM_SCROLL_LINES; i++) {
lines[i]= Image.Text("",0,0,0);
message_sprite[i] = Sprite();
message_sprite[i].SetX (Window.GetX() + (screen_width / 2 ) - (LINE_WIDTH * CHAR_WIDTH / 2));
message_sprite[i].SetY (Window.GetY() + (screen_height / 2) + (logo_height /2) +(logo_height * 1.2)+ (i * CHAR_HEIGHT * 2) );
message_sprite[i].SetZ (10000);
}
pretext = String("");
fun scroll_message_callback(text) {
nobreak = 0;
if (text.CharAt(0) == ">") { # "no linebreak" flag, like "-n"
text = text.SubString(1, StringLength(text)); # remove ">" at front
nobreak = 1;
}
if (pretext == "") {
if (nobreak == 1) pretext = text;
// Truncate the message if too long
if (StringLength(text) > LINE_WIDTH) {
text = text.SubString(0, LINE_WIDTH - 3);
text += "...";
}
// Shift messages one up
for (i = 0; i < NUM_SCROLL_LINES - 1; i++) {
lines[i] = lines[i+1];
}
else { # the previous message was flagged to have no linebreak
// Truncate the message if too long
if (StringLength(text) > LINE_WIDTH - 5) { # leave min. 5 for pretext
text = text.SubString(0, LINE_WIDTH - 8);
text += "...";
}
# Truncate the previous message if too long
if (StringLength(pretext) > (LINE_WIDTH - StringLength(text))) {
pretext = pretext.SubString(0, LINE_WIDTH - StringLength(text) - 3);
pretext += "...";
}
text = pretext + text;
if (nobreak == 1) pretext = text;
else pretext = "";
}
// Create the image for the latest message
# original script had "lines[i]"
lines[i] = Image.Text( text, 0.5, 0.5, 0.5);
// Re-allocate the text images to sprites
for (i = 0; i < NUM_SCROLL_LINES; i++) {
message_sprite[i].SetImage(lines[i]);
}
}
Plymouth.SetUpdateStatusFunction(scroll_message_callback);
# messages get added to updates
Plymouth.SetMessageFunction(scroll_message_callback);
#----------------------------------------- Quit --------------------------------
fun quit_callback ()
{
anim.sprite.SetOpacity (0);
if (Plymouth.GetMode() == "shutdown") {
motif.sprite.SetOpacity(0);
}
}
Plymouth.SetQuitFunction(quit_callback);
OK, więc podałem prawie wszystkie potrzebne informacje, jeśli ktoś jest zaznajomiony z tym, daj mi znać, czego mi brakuje, aby przekazać komunikaty rozruchowe do Plymouth. Dzięki
Odpowiedzi:
OK, więc pracuję nad tym problemem od 4 dni i prawie go całkowicie przybiłem. Do tej pory udało mi się zmusić Plymouth do uruchomienia z wyświetlonymi komunikatami, ale niestety wiadomości są obcinane. Obecnie próbuję ulepszyć skrypty, ale nie wiem, gdzie jest problem w skrypcie / lib / lsb / init-functions lub /lib/plymouth/themes/"theme-name"/mdv.script.
Oto moja dotychczasowa praca.
najpierw musisz ustawić funkcje inicjujące na wysyłanie wiadomości do Plymouth, tak aby wyglądało to tak (przejdź przez każdą linię, aby zobaczyć różnice i skopiuj linię odpowiadającą wysyłaniu Plymouth):
Teraz po dodaniu tego do funkcji init musisz edytować motyw Plymouth mdv.script
To jest moja najnowsza zaktualizowana wersja skryptu:
Zasadniczo skrypt można zastosować do dowolnego motywu, wystarczy podać nazwy plików obrazów w folderze. I zmieniając kilka innych linii, aby dostosować obrazy na ekranie. Albo to, co robisz, to kopiowanie niezbędnej części, np. Powiedzmy, że chcesz część postępu, więc wszystko, co musisz zrobić, to skopiować wszystko z
----------------------------------------- Pasek postępu ------- -------------------------
do
----------------------------------------- Aktualizacja statusu ------- -------------------------
Po zakończeniu edycji skryptu mdv.script upewnij się, że
sudo update-initramfs -u
przy następnym uruchomieniu zobaczysz nowy splash.Zapoznaj się z linkami podanymi w moim pytaniu, które są bardzo pouczające i pozwolą Ci zrozumieć skrypty Plymouth w krótkim czasie.
Teraz, jeśli zrobiłeś wszystko, co powiedziałem tutaj, powinieneś uruchomić przewijanie wiadomości. Teraz, jeśli chodzi o część obciętą, pracuję nad tym, ale to trochę denerwujące, że muszę ponownie uruchamiać maszynę za każdym razem, gdy wprowadzam jakieś zmiany. Czy to możliwe, aby przetestować proces uruchamiania podczas am zalogowany jak
Innym sposobem na przetestowanie Plymouth jest skopiowanie powyższego polecenia do pliku tekstowego i dodanie,
sudo plymouth update --status="your message"
aby przewijać więcej wiadomości. Następnie uczyń plik wykonywalnym i uruchom w terminalu.Mam nadzieję, że pomoże to wszystkim, którzy chcą edytować swój plymouth. Powodzenia!!!
źródło
wiem, że to stary wątek, ale myślę, że znam odpowiedź na temat obcięcia tekstu, czy nie. W moim skrypcie themename.script (nie w pliku themename.plymouth) używam dwóch zmiennych.
za pomocą tych zmiennych mogę ustawić, ile linii będzie wyświetlanych i jak długo będą wyświetlane linie. Skrypt ma również funkcję, która przycina linie, jeśli mają być wyświetlane zbyt długo.
Mam nadzieję, że to będzie komuś pomocne.
Mój problem w opensuse 42.1 Leap is. plymouth nie pokazuje komunikatów rozruchowych, jakby były zapisane w /var/log/boot.log. Pokazuje systemowe wezwania do świadczenia usług.
W ten sposób edytowałem również / lib / lsb / init-functions
albo to
Nic mi nie działało. Czy ktoś ma pomysł?
Oto istnienie skryptu themename.script, którego używam
źródło