I want to do the following thing: I want to replace the systemd program on my CentOS 7 installation, with a script, that will eventually start a shell where the user can input commands as root on the system console.
For this, I used the init=/sbin/myInit parameter. In this script I do some initialization, and in the end I call bash to enable the user to input commands. The interactive bash always appears on the screen.
Unfortunately, there is a problem with the input, that I haven't been able to solve: the input doesn't work correctly. When I press enter, only the second enter works, but no new line is performed on the screen. And when I type some characters, not all the characters are read. It seems like the console is in some Unicode mode (stty -a shows iutf8 parameter), and bash cannot correctly read the input. The output is fine, all the echo commands in my script are correctly printed on the screen (I only print ASCII characters).
I've tried all sorts of combinations, with different LC_ALL settings (LC_ALL=C, LC_ALL=C.utf-8, no LC_ALL or LANG variables initialization), redirect stdin/stdout/stderr to /dev/console, /dev/tty0 or /dev/tty1, the TERM variable is initialized to linux value, but nothing works. I tried unicode_start and unicode_stop commands, but unicode_stop doesn't work, and I get the error message "stty: standard input: unable to perform all requested operations". If I run showkey command, and I press the enter key, the correct keycode 28 is detected, same with normal boot.
Even stranger than this is the fact that if I'm using the init=/bin/bash kernel parameter, the input works fine, and if I manually run my script, it also works fine. If I copy the bash executable to something like /bin/mys, and I use init=/bin/mys, than same input problem occurs. It seems like the initrd image treats /bin/bash differently. Maybe it performs some initialization or something, that enables the bash to read correctly from the terminal. Why do we have this difference between init=/bin/bash and init=/bin/mys? It's the same executable in the end.
What am I doing wrong ?
As a general question about the init program, can somebody explain me what the init program should do to work correctly ? Any particular signals it has to respond to, any console initialization to be performed ?
I'm trying to solve this for days, and I cannot find any solution. On the web I couldn't find any article about this. So any suggestion would be greatly appreciated. Thank you.
I managed to pull a solution out for this one.
Turns out, at boot, the console is not initialized. I looked at the differences between the output of stty -a between the normal boot and the script boot (init=/sbin/myInit), and there are some differences between them: the console on normal boot had the following flags active on it: brkint ignpar ixon imaxbell isig icanon iexten echo, while when on script boot, those flags where cleared (stty reports them with - ). I'm not sure what they mean, except the echo flag, which I quickly noticed, because on each key press, no character ware printed on the screen.
So I decided to set those flags on my init script for /dev/console. After digging the stty manual page, I found the sane option, that sets the most important flags for normal console usage. So I added the line stty -F /dev/console sane in my init script.
But, there is a small problem. It seems that some console options cannot be changed by the stty command if the console is already opened by a process. So the first thing I did in my script is to redirect the stdin/stdout/stderr to /dev/null, via the line 0/dev/null, and then add the stty sane line, then redirect back the stdin/stdout/stderr to /dev/console.
I also noticed a process called plymouth, probably started by the CentOS initrd, so before the root was mounted and init script executed. I'm not sure if that process opened the system console, but I decided to eliminate it, by reconstructing a personalized initrd, by omitting the plymouth module from dracut (option -o plymouth).
After doing this, the script worked fine, and the bash process started by the script could read correctly the console.
Hope this helps somebody someday. Cheers
Related
While installing a new RHEL on KVM host I am displaying a text file using more command. Problem is more is behaving like cat in virt-manager i.e. not displaying page-by-page and directly scrolling to the end of the page. I tried using less instead of more but it is displaying the same behavior.
Can anyone suggest what could be the reason for this?
Edit Based on comments I tried changing TERM to xterm during first boot. But that didn't have any effect. I tried this command export TERM=xterm
I got the env variables printed. I am pasting it hoping this might be a clue.
Edit I couldn't get it working. I noticed that before the script is executed, some other script is running and this might be setting some environment variable because of which more isn't working. I am now calling more command before this script start executing. And now it is working.
I suspect your environment is not correct. Specifically your $TERM environment variable may not be set. See here for the more manual entry.
The more command respects the following environment variables, if
they exist:
MORE This variable may be set with favored options to more.
SHELL Current shell in use (normally set by the shell at login
time).
TERM The terminal type used by more to get the terminal
characteristics necessary to manipulate the screen.
VISUAL The editor the user prefers. Invoked when command key v is
pressed.
EDITOR The editor of choice when VISUAL is not specified.
After help from a senior dev, I found out what was happening behind the scenes.
Suppose A.sh is executing more command like below:
more pathtofile
A.sh is being called by some other script like below:
pathtoA.sh | tee
Because of this tee command, more command in child script was not behaving as it should have been.
I am trying to schedule the execution of a shell-script with the Linux tool "at".
The shell script (video.sh) looks like this:
#!/bin/sh
/usr/bin/vlc /home/x/video.mkv
The "at" command:
at -f /home/x/video.sh -t 201411052225
When the time arrives, nothing happens.
I can execute the shell-script just fine via console or by rightclicking - Execute. VLC starts like it is supposed to. If I change the script to e.g. something simple like
#!/bin/sh
touch something.txt
it works just fine.
Any ideas, why "at" will not properly execute a script that starts a graphical program? How can I make it work?
You're trying to run an X command (a graphical program) at a scheduled time. This will be extremely difficult, and quite fragile, because the script won't have access to the X server.
At the very least, you will need to set DISPLAY to the right value, but even then, I suspect you will have issues with authorisation to use the X screen.
Try setting it to :0.0 and see if that works. But if you're logged out, or the screensaver's on, or any number of other things...
(Also, redirect vlc's stdout and stderr to a file so that you can see what went wrong.)
Your best bet might be to try something like xuserrun.
I suspect that atd is not running. You have to start the atd daemon before (and to set DISPLAY variable like chiastic-security said) ;)
You can test if atd is running with
pidof atd &>/dev/null && echo 'ATD started' || echo >&2 'ATD not started
Your vlc command should be :
DISPLAY=:0 /usr/bin/vlc /home/x/video.mkv
(Default display)
I use the command xdg-open quite a lot in my Ubuntu Linux terminal. However, two things irk me:
Is it possible to suppress the error messages?
Is it possible to get the command to always complete? (That is, not continue running, so that I have another "new line" in my terminal).
I realize 2 may not be possible, because of the way the program works, but I imagine 1 is.
First one is easy. Just
alias xdg-open="xdg-open 2>/dev/null"
If you want it permanently, just add that line to ~/.bashrc file.
I recommend you to think twice if you want to become blind to errors, though.
The second one is quite confusing to me. xdg-open shouldn't be intereactive. In my computer (Debian sid) xdg-open execs the command and ends, even if the command itself has not ended (ie: you have not closed the application opened for the URL). I think this should be the behaviour of xdg-open on any platform (it's supposed to work exactly the same way on any XDG system, that's its very purpose).
Anyway, for any command you launch in a shell, if you want it to be non-interactive, that is, to allow to enter commands even if the previous one hasn't finished, you just attach "&" to the end of it. Example:
# prompt is not shown until you close the calculator
$ gnome-calculator
# prompt is shown right after opening calculator and you can
# work on the shell even if you don't close it
$ gnome-calculator &
I maybe late for the answer, but I got exactly the same problem like you have / had.
I tried to start a URL with xdg-open, my default browser is firefox, and not xdg-open but firefox started with an error:
[user#user-pc ~]$ xdg-open https://www.google.de # the page opens fine, but firefox had an error
[user#user-pc ~]$
(process:3783): GLib-CRITICAL **: g_slice_set_config: assertion 'sys_page_size == 0' failed
# needed to press enter here
xdg-open closed fine but the firefox error stayed and I need to press enter to get the bash moving.
To get along this problem I called xdg-open within a new shell putting those output to /dev/null:
bash -c "xdg-open https://www.google.de" 2> /dev/null
The page opened fine, no error shown – rather nothing has been shown. And no need to press enter.
I have written a Fortran program (let's call it program.exe) with does some simulation for me. Via ssh I'm logging ino some far away computers to start runs there whose results I collect after a few days. To be up-to-date how the program proceeds I want to write the shell output into a text file output.txt also (since I can't be logged in the far away computers all the time). The command should be something like
nohup program.exe | tee output.txt > /dev/null &
This enables me to have a look at output.txt to see the current status even though the program hasn't ended its run yet. The above command works fine on my local machine. I tried first with the command '>' but here the problem was that nothing was written into the text file until the whole program had finish (maybe related to the pipe buffer?). So I used the workaround with 'tee'.
The problem is now that when I log into the computer via ssh (ssh -X user#machine), execute the above command and look at output.txt with the VI editor nothing appears until the program has finished. If I omit the 'nohup' and '&' I will not even get any shell output until it has finished. My thought was that it might have to do something with data being buffered by ssh but I'm rather a Linux newbie. For any ideas or workaround I would be very grateful!
I would use screen utility http://www.oreillynet.com/linux/cmd/cmd.csp?path=s/screen instead of nohup. Thus I would be able to set my program to detached state (^A^D) reconnect to the host, retrieve my screen session (screen -r)
and monitor my output as if I never logged out.
I've got a strange problem. After I enter my password on a debian 6.0 system, I get the motd but then there is a 5-10 second pause until I get a shell prompt. If I press ctrl-c during that pause the prompt comes up instantly. What could be happening here? Am I killing the login process? Why might it be taking so long to invoke bash? I appreciate any suggestions.
Thanks
You can debug bash shell scripts using set -x and set +x. The set -x command enables debug mode and the set +x command disables it.
Putting set -x at the top of your $HOME/.bash_profile should cause debug information to be printed for your personal shell initialisation files. If as you say you get a 10 second delay you should be able to track it down quite easily. If This doesn't shed any light then go for the system wide initialisation file /etc/profile.
Bash Debugging and shell initialisation files
It's likely there's something in your .bashrc or .bash_profile. Or maybe some other startup file (/etc/profile et al).
Same problem as John Rix for me. /opt/vmware/bin/ovfenv was the culprit.
I found this post after doing the following investigation:
starting another bash would take up to 30 seconds on a CentOS6
strace bash
shows few lines before it hangs:
read(3, "LANG=`/opt/vmware/bin/ovfenv --q"..., 183) = 183
Removed the script from being executed with:
mv /etc/profile.d/zzzz-vamilocale.sh /etc/profile.d/zzzz-vamilocale.sh.ko