WelcomeWelcome | FAQFAQ | DownloadsDownloads | WikiWiki

Author Topic: Core-11.1 Executing Bash script from profile.d - Runs 2 times before Exiting  (Read 1257 times)

Offline pek

  • Newbie
  • *
  • Posts: 19
Hi, I tried to make my own tcz to be loaded and run right after login. (Like autoexec.bat in DOS).
It works.
But it runs the scripts 2 times before exiting.

** My base is Core-11.1 (CLI only).

** mytcz.tcz has these:
/thescript.sh
/etc/profile.d/callscript.sh

** the reason I use callscript.sh to call and execute thescript.sh is because
thescript.sh is a BASH script (it will not run in profile.d since only sh script is run in here)
And yes I also loaded bash.tcz and all necessary tcz needed upon boot


** content of callscript.sh
Code: [Select]
#!/bin/sh
bash /thescript.sh


** content of thescript.sh (simplified version)
Code: [Select]
#!/usr/local/bin/bash
serial=$(sudo dmidecode -s system-serial-number)

ask(){
echo $serial
echo "Press ENTER or Space to continue"
echo "Any other key to start over and replace mistakes"
read allOK
}

upload(){
send=details.csv
echo $serial >> $send && echo -n , >> $send
curl -a -T $report ftp://myserver.com --disable-epsv -#
res=$?
if test "$res" != "0"; then
echo "Upload FAILED..!! with error code $res"
read
else
echo "SAVED and uploaded NOW..!!"
read
fi
echo 'bye..:)'
}

clear
ask
until [ -z $allOK ]
do clear
ask
done
upload


-----------------------------------------------------------------------------

Now like I said in the beginning. It works. However I get this result:
1. It shows the serial number
2. When I press ENTER it will upload the result as expected.
BUT.....
3. It will redo 1 and 2 again. Then exit  :o
So I end up having a details.csv in my server with 2 duplicate entries of serial numbers.

??? How do I make this exit after number 2

Thanks.

** Side note
If I run thescript.sh manually (not through profile.d)
eg: $ bash thescript.sh
It will run as expected (exit after step 2)  ???
« Last Edit: October 11, 2020, 06:10:42 PM by pek »

Offline polikuo

  • Sr. Member
  • ****
  • Posts: 456
Hi, I tried to make my own tcz to be loaded and run right after login.

Is there a reason that you must use /etc/profile.d/ scripts to call your script on log-in ?

~/.profile can do the same.

Just append bash /path/to/the/script to that file will call the script (every time) right after you log-in.

Offline pek

  • Newbie
  • *
  • Posts: 19
Hi, I tried to make my own tcz to be loaded and run right after login.

Is there a reason that you must use /etc/profile.d/ scripts to call your script on log-in ?

~/.profile can do the same.

Just append bash /path/to/the/script to that file will call the script (every time) right after you log-in.

Hi, thanks for your reply.
No particular reason. I just want the script to be executed automatically (like autoexec.bat style).

I'm at work now. I'll try this later tonight.
However, I think I tried to make a tcz for ~/.profile before but it dissapeared and got replaced with default .profile after booting.
So the tcz i made was:
/home/tc/.profile

and in the .profile i made
Code: [Select]
#!/bin/sh
echo "Hello..!!"

However after booting, nothing was echoed.
And when I cat ~/.profile
It was replaced with default .profile entries from original Tinycore and my code lines were gone.

Any suggestion to make tcz that can append ~/.profile ??
ps. I think this probably achievable by remastering. But I prefer to go the tcz route if possible. For portability reason. So I can easily just copy mytcz and use it on any copy fresh tinycore linux.
Thanks.

Offline Rich

  • Administrator
  • Hero Member
  • *****
  • Posts: 8440
Hi pek
Welcome to the forum.

... ** the reason I use callscript.sh to call and execute thescript.sh is because
thescript.sh is a BASH script (it will not run in profile.d since only sh script is run in here)

And yes I also loaded bash.tcz and all necessary tcz needed upon boot
...
Since  bash.tcz  is loaded and  thescript.sh  contains the correct shebang (#!/usr/local/bin/bash) you should be able to
call it directly like this:
Code: [Select]
/Path/To/thescript.sh
Create a dependency file for  mytcz.tcz  called  mytcz.tcz.dep. It needs to contain:
Code: [Select]
bash.tcz
curl.tcz
dmidecode.tcz

Set up  mytcz.tcz  so it look like this:
Code: [Select]
/usr/local/bin/thescript.sh
/usr/local/tce.installed/mytcz
Run  chmod 775  on both files so they are executable.

/usr/local/tce.installed/mytcz  gets executed automatically after  mytcz.tcz  gets loaded Try placing this in that file:
Code: [Select]
#!/bin/sh
thescript.sh &

Offline polikuo

  • Sr. Member
  • ****
  • Posts: 456
Hi pek.

Judging by the script, I'm fairly certain that your script has to be executed as a user not root.
If that's the case, tce.installed is NOT going to do the trick.

Besides, Google says:
Quote
autoexec.bat is a startup file used with MS-DOS and early versions of Microsoft Windows operating systems (Windows 3.x and Windows 95). It contains commands that are to be executed by the operating system when the computer first boots.

It would be easier to answer your question if you could share more details.

Who is going to run the script ?
  root / tc

When should it executes ?
  every time you boot / every time you log-in / every time you load the extension

However after booting, nothing was echoed.
And when I cat ~/.profile
It was replaced with default .profile entries from original Tinycore and my code lines were gone.
Did you make a backup ?
I suggest you take a few minutes and read the book to understand the TC philosophy.

Offline pek

  • Newbie
  • *
  • Posts: 19
Hi Rich,
Thanks for your suggestions.
Quote
/usr/local/tce.installed/mytcz  gets executed automatically after  mytcz.tcz  gets loaded Try placing this in that file:
#!/bin/sh
thescript.sh &
this makes the script runs line by line without waiting for user input (read command) and grabbing focus on and off between $ prompt and the running script.

By removing & fixed it. Now it becomes
Quote
#!/bin/sh
thescript.sh
It seems to behave as I wanted..  ;D

However, now I realized that it did not create details.csv anywhere at all. As part of the command in thescript.sh
Quote
send=details.csv
echo $serial >> $send && echo -n , >> $send
Perhaps because all of this is run before the tree structure is constructed??

So, what happens is after the script finish running, then the boot process continue to
setting keymap to us Done.
setting hostname to box Done.
then prompt tc@box$

I did ls in ~
/usr/local/bin
/usr/local/tce.installed
but the details.csv is not there

I also added sudo thescript.sh but still nothing.

note: if I run thescript.sh manually after the prompt (eg. tc@box$)
It will create details.csv

Is there anyway to make thescript.sh run automatically after the prompt?? Can you please tell me. Thanks.
I need to have details.csv for backup when the upload fails.

Thank you  :)

Offline pek

  • Newbie
  • *
  • Posts: 19
Hi polikuo,
Quote
Who is going to run the script ?
  root / tc
Anyone. Whoever is easier to accomplish.

Quote
When should it executes ?
  every time you boot / every time you log-in / every time you load the extension
Every time I boot. And it also need to store a csv/text file automatically.

Quote
Did you make a backup ?
I suggest you take a few minutes and read the book to understand the TC philosophy.
I don't quite understand what backup should I make.
I read the book many hours back and forth before I attempted to do this. I learn a lot from the book and I also don't understand a lot from it  ;D
Therefore I seek interactive help from others in this forum. Because for sure I must have missed something from the book.
I'm hoping someone can point me out the things that I've missed / did not understand.

Thank you..  :)

Offline polikuo

  • Sr. Member
  • ****
  • Posts: 456
Hi polikuo,
Quote
Who is going to run the script ?
  root / tc
Anyone. Whoever is easier to accomplish.
I've been telling you, you need to specify who will be running script.

Whenever you run sudo as root, nothing happens.

note: if I run thescript.sh manually after the prompt (eg. tc@box$)
It will create details.csv

I can see obviously now the answer is tc instead of root.

Anything under /usr/local/tce.installed is executed as root WHEN an extension is loaded.

Plus that script would only be executed once.

If you log out and log in again, nothing happens.

If you're happy with that, then change the content of your /usr/local/tce.installed/mytcz to something like:
Code: [Select]
#!/bin/sh
su tc -c 'thescript.sh'

Quote
When should it executes ?
  every time you boot / every time you log-in / every time you load the extension
Every time I boot. And it also need to store a csv/text file automatically.

Since you want that interactive tcz to run onboot, I suggest you put that tcz at the end of your onboot.lst to avoid messing up the booting process.

I don't quite understand what backup should I make.
I read the book many hours back and forth before I attempted to do this. I learn a lot from the book and I also don't understand a lot from it  ;D
Therefore I seek interactive help from others in this forum. Because for sure I must have missed something from the book.
I'm hoping someone can point me out the things that I've missed / did not understand.

Tiny Core is a very unique distro.
By default, most directory are stored in RAM which will vaporize upon every reboot.
We backup those files before shutting down and restore those stuff every time we boot.

Offline Rich

  • Administrator
  • Hero Member
  • *****
  • Posts: 8440
Hi pek
You might want to add a path to this so you can control where it gets saved:
Code: [Select]
send=details.csv
If you do this, it will be saved to your home directory:
Code: [Select]
read USER < /etc/sysconfig/tcuser
send="/home/$USER/details.csv"

If you shutdown your computer using this command:
Code: [Select]
exitcheck.shyour home directory will get backed up prior to shutting down and your  /home/$USER/details.csv  file will be restored the
next time you power up. The problem with that is backups get restored after extensions get loaded and the file you create
will likely get overwritten, so your script needs to know when its safe to start executing its commands.

... By removing & fixed it. Now it becomes
Quote
#!/bin/sh
thescript.sh
It seems to behave as I wanted..  ;D ...
If you do that, any scripts in  /usr/local/tce.installed/  that have not yet run will be blocked until yours finishes. That may
or may not be a problem, but it may be an issue if your extension is not loaded last.

You may want to put that  &  back in there and have  thescript.sh  determine when it's safe to start executing
its commands. If you add something like this to the start of  thescript.sh:
Code: [Select]
while true
do
    sleep 2
    busybox ps | grep -E 'tc-config|tce-|filetool|tce.installed|bootlocal|bootsync|.profile' | grep -qv grep
    [ "$?" == 0 ] && continue
    break
done
I think that will insure that all of the startup code has completed prior to  thescript.sh  resuming execution.

Offline pek

  • Newbie
  • *
  • Posts: 19
Hi Rich,
This works really well.  :)
Quote
read USER < /etc/sysconfig/tcuser
send="/home/$USER/details.csv"
Now I have the details.csv saved in ~

I tried this, but it does same thing like I said earlier. (It runs all script line by line without waiting for user input (read command) till the end of script).  :o
Quote
You may want to put that  &  back in there and have  thescript.sh  determine when it's safe to start executing
its commands. If you add something like this to the start of  thescript.sh:
Code: [Select]
while true
do
    sleep 2
    busybox ps | grep -E 'tc-config|tce-|filetool|tce.installed|bootlocal|bootsync|.profile' | grep -qv grep
    [ "$?" == 0 ] && continue
    break
done
I think that will insure that all of the startup code has completed prior to  thescript.sh  resuming execution.
If I removed &, the boot hangs after loading the tcz.
So I removed & and the "while true... code" all together. Then it works as I wanted... up to the saving file part.
----------------------------------------------------------------------------

Now, the last bit of the my problem... Sorry I thought the curl worked last night eventhough I received Failed(7) Error.
I thought that's because I tested this offline.

Now I'm in the network. FTP server is up and running. 8)
I tested the command curl -a -T $report ftp://192.168.1.2 --disable-epsv -# manually at the prompt and it works well.
But...
It will return Failed(7) Error when I let it boot up and automatically run from the script. (The same when I put the & back at the mytcz)

What's wrong?? Perhaps the ethernet is not up yet when the tcz is running?
Please help to solve this bit. Thanks.
« Last Edit: October 12, 2020, 05:32:45 PM by pek »

Offline pek

  • Newbie
  • *
  • Posts: 19
Hi polikuo,
Thank you very much for the information. I learn more things each time.  :)

Offline Rich

  • Administrator
  • Hero Member
  • *****
  • Posts: 8440
Hi pek
...
Quote
You may want to put that  &  back in there and have  thescript.sh  determine when it's safe to start executing
its commands. If you add something like this to the start of  thescript.sh:
Code: [Select]
while true
do
    sleep 2
    busybox ps | grep -E 'tc-config|tce-|filetool|tce.installed|bootlocal|bootsync|.profile' | grep -qv grep
    [ "$?" == 0 ] && continue
    break
done
I think that will insure that all of the startup code has completed prior to  thescript.sh  resuming execution.
If I removed &, the boot hangs after loading the tcz. ...
It hung because its located in  /usr/local/tce.installed  and won't complete until  thescript.sh  completes and returns control
to it.  That  while true  loop won't break since  tce.installed  shows up in the  ps  command so  thescript.sh  just waits there.

Quote
What's wrong?? Perhaps the ethernet is not up yet when the tcz is running?
That's probably it. It probably gets brought up by  /opt/bootlocal.sh  which doesn't run until after all extensions are loaded.

You can use this code in  thescript.sh  to block execution until the network is up:
Code: [Select]
# Wait for network to come up
SEC=60
while [ $SEC -gt 0 ]
do
        $(( SEC-- ))
        ifconfig | grep -q "Bcast:" && break
        sleep 1
done
but you will need to put that  &  back in.

Offline pek

  • Newbie
  • *
  • Posts: 19
Hi Rich,
Yes, I have to put the & back to make it work.
Now, it creates the file and also uploads to ftp server.  ;)

Buuttt... strangely, as happened from the beginning, whenever I put the & back, the script will just keep running line by line, ignoring "READ" tag, "IF" tag or "WHILE" tag.
Like I said earlier. Hence my reason to remove the &.
But when I removed it, the script will hang because blocking other process. So removing & is not an option.

It's a dilemma now.
If the script ignoring user input or loops. Then it's also useless.

eg. if I change the last line of the thescript.sh into poweroff
Code: [Select]
...
clear
ask
until [ -z $allOK ]
do clear
ask
done
sudo poweroff
the result is it will poweroff the machine straight away despite of any loop or "READ" for user input tag declared.

Any suggestions?? Thanks.

Offline polikuo

  • Sr. Member
  • ****
  • Posts: 456
The standard way to run any script on boot is via /opt/bootlocal.sh

I've been trying to ask you: MUST it be a tcz and no other way ?

Since you emphasize you want a tcz to do that, I crossed out that option.

Anyway, append this line in /opt/bootlocal.sh:
Code: [Select]
[ -f /usr/local/tce.installed/TheNameOfYourTCZ ] && su tc -c 'blablabla'
Remember to remove the /usr/local/tce.installed/TheNameOfYourTCZ script from your package,
 so it won't be executed again.

Or much simpler way:
Forget about your extension.
Just copy that script to /home/tc/.local/bin
Then add
Code: [Select]
su tc -c '/home/tc/.local/bin/the_script'
to your /opt/bootlocal.sh instead.

Note that whether adding a '&' at the end of the line or not would not affect anything.

That script is also executed as root, so make sure you switch back to tc with su tc -c 'blablabla'

Offline pek

  • Newbie
  • *
  • Posts: 19
Hi polikuo,
Yes, I guess it can't be done through tcz only at this stage. (As tcz can not append and sadly it will be overwritten if original file existed).
I have to go the remastering path then.

And thank you very much for pointing out
Quote
The standard way to run any script on boot is via /opt/bootlocal.sh
I'll try this later tonight, when I have access to remastering pc.
I think this should work  :)