Reputation: 5999
I want a command to be excuted after busybox ash starts.
I saw here that busybox ash is debian ash variant, and after seeing here, tried setting
ENV=$HOME/.shinit; export ENV
in file /etc/profile, and adding (BTW, this is to make Ctrl-C work in the shell)
setsid cttyhack sh
in file /.shinit.
But when I entered the shell, the 'ENV' variable is not set. (echo $ENV
shows nothing).
How should I do it? By the way, my shell doesn't ask for loging(no login shell).
ADD :
This is my /init script.
#!/bin/sh
echo "### INIT SCRIPT ###"
mkdir /proc /sys /tmp
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs none /tmp
echo -e "\nThis boot took $(cut -d' ' -f1 /proc/uptime) seconds\n"
mknod /dev/virtual_buffer c 125 0
#ifconfig eth0 10.0.2.15 netmask 255.255.255.0 up
#route add default gw 10.0.2.2
echo "### calling /bin/sh ###"
exec /bin/sh
Upvotes: 1
Views: 1000
Reputation: 94849
After seeing your boot script, and duplicating exactly what you present above I experienced the joys of infinite sh#
prompts.
Your problem is that you're entering an infinite loop. To explain what's happening, we follow the logic in your script.
When you invoke the shell with the --login
option, it reads /etc/profile
. This has a line reading:
ENV=$HOME/.shinit; export ENV
which, at the end of processing the profile is sourced.
This file contains the line: setsid cttyhack sh
This launches a new copy of sh
, which has been pre-armed with an ENV
variable, which causes it to issue setsid cttyhack sh
… repeat until your screen is covered in shell prompts and you're scratching your head.
The solution is even simpler than you think. Rather than getting the ENV file to load that cttyhack, move it into the init
script, i.e. at the bottom of the init script, instead of just sh
do:
exec setsid cttyhack sh --login
Don't add the line to the .shinit
with the setsid cttyhack sh
, and you don't end up with an infinite loop.
/etc/profile
initiallyYou pretty much answered the issue in your question, when you mentioned:
By the way, my shell doesn't ask for loging(no login shell)
So I'm guessing that you're launching it with something like: busybox ash
, without any arguments.
There are two modes for launching a shell - as a 'login' type shell and as a 'non-login' type shell. This governs the launch behavior.
When you invoke a login-type shell, it will read the /etc/profile
file and the ~/.profile
files. This can be seen in the source -
behavior on isloginsh
:
if (argv[0] && argv[0][0] == '-')
isloginsh = 1;
if (isloginsh) {
const char *hp;
state = 1;
read_profile("/etc/profile");
state1:
state = 2;
hp = lookupvar("HOME");
if (hp)
read_profile("$HOME/.profile");
}
The detection of isloginsh
can also be set by passing in the -l
or --login
options, where the argument parser checks if the -l
or --login
options are passed:
} else if (cmdline && (c == 'l')) { /* -l or +l == --login */
isloginsh = 1;
Upvotes: 0