Simple bash problem related to executing command after previous has stopped (I am not programmer) - bash

#!/bin/sh
xmodmap -e "keycode 49 = equal plus"
cd /media/5F53-7973/BGTrilogy/
wine ./bgmain.exe
xmodmap -e "keycode 49 = dead_caron dead_tilde dead_caron dead_tilde notsign notsign"
Basically what I want from it is that the last entry would only run after I quit wine ./bgmain.exe.
What's the most foolproof way to do it?

Try adding wait on a line after the wine command.

Related

Why isn't this command returning to shell after &?

In Ubuntu 14.04, I created the following bash script:
flock -nx "$1" xdg-open "$1" &
The idea is to lock the file specified in $1 (flock), then open it in my usual editor (xdg-open), and finally return to prompt, so I can open other files in sequence (&).
However, the & isn't working as expected. I need to press Enter to make the shell prompt appear again. In simpler constructs, such as
gedit test.txt &
it works as it should, returning the prompt immediately. I think it has to do with the existence of two commands in the first line. What am I doing wrong, please?
EDIT
The prompt is actually there, but it is somehow "hidden". If I issue the command
sudo ./edit error.php
it replies with
Warning: unknown mime-type for "error.php" -- using "application/octet-stream"
Error: no "view" mailcap rules found for type "application/octet-stream"
Opening "error.php" with Geany (application/x-php)
__
The errors above are not related to the question. But instead of __ I see nothing. I know the prompt is there because I can issue other commands, like ls, and they work. But the question remains: WHY the prompt is hidden? And how can I make it show normally?
Why isn't this command returning to shell after &?
It is.
You're running a command in the background. The shell prints a new prompt as soon as the command is launched, without waiting for it to finish.
According to your latest comment, the background command is printing some message to your screen. A simple example of the same thing:
$ echo hello &
$ hello
The cursor is left at the beginning of the line after the $ hello.
As far as the shell is concerned, it's printed a prompt and is waiting a new command. It doesn't know or care that a background process has messed up your display.
One solution is to redirect the command's output to somewhere other than your screen, either to a file or to /dev/null. If it's an error message, you'll probably have to redirect both stdout and `stderr.
flock -nx "$1" xdg-open "$1" >/dev/null 2>&1 &
(This assumes you don't care about the content of the message.)
Another option, pointed out in a comment by alvits, is to sleep for a second or so after executing the command, so the message appears followed by the next shell prompt. The sleep command is executed in the foreground, delaying the printing of the next prompt. A simple example:
$ echo hello & sleep 1
hello
[1] + Done echo hello
$
or for your example:
flock -nx "$1" xdg-open "$1" & sleep 1
This assumes that the error message is printed in the first second. That's probably a valid assumption for you example, but it might not be in general.
I don't think the command is doing what you think it does.
Have you tried to run it twice to see if the lock cannot be obtained the second time.
Well, if you do it, you will see that it doesn't fail because xdg-open is forking to exec the editor. Also if it fails you expect some indication.
You should use something like this
flock -nx "$1" -c "gedit '$1' &" || { echo "ERROR"; exit 1; }

Send keystroke to Dockerfile, Ubuntu

I'm creating Dockerfile script and it has a command line that executes a program and requires user input 1 from keyboard as selected option to go to further steps.
Xdotool, man yes or expect cannot help in this situation.
Update source-code:
First off, download and extract RevoMath library, navigate to RevoMath folder then execute the install script.
...
RUN wget -q https://mran.microsoft.com/install/mro/3.2.4/RevoMath-3.2.4.tar.gz
RUN tar -xzf RevoMath-3.2.4.tar.gz
RUN cd RevoMath/
RUN ./RevoMath.sh
...
Install script has some select options as follow:
echo "1. Install MKL"
echo "2. Uninstall MKL"
echo "3. Exit utility"
We need to enter 1 from keyboard to install. How can we do it via Docker command?
Any help would be appreciated!
If I correctly understand you, you would like to add echo 1 | before ./RevoMath.sh in your Dockerfile:
...
RUN cd RevoMath/ && echo 1 | ./RevoMath.sh
...
BTW: In your example this lines will not work as you expected:
RUN cd RevoMath/
RUN ./RevoMath.sh
Because each RUN is an independent execution.
You should use && if you want to execute RevoMath.sh script from specific folder (see my example in the beginning)
I suggest to use redirect from standard input.
For example install.sh required some input(s) from user at execution time.
Suppose you need to enter 1 as a response to first interaction(questions) and
then you have another response as y for further interaction then it's good to use redirect from stdin.
$#>install.sh <EOF
$#>1
$#>y
$#>EOF
This way whenever script is waiting for inputs it will answer as 1 for the first question and y for the second question.

Repeating Bash Task using At

I am running ubuntu 13.10 and want to write a bash script that will execute a given task at non-pre-determined time intervals. My understanding of this is that cronjobs require me to know when the task will be performed again. Thus, I was recommended to use "at."
I'm having a bit of trouble using "at." Based on some experimentation, I've found that
echo "hello" | at now + 1 minutes
will run in my terminal (with and without quotes). Running "atq" results in my computer telling me that the command is in the queue. However, I never see the results of the command. I assume that I'm doing something wrong, but the manpages don't seem to be telling me anything useful.
Thanks in advance for any help.
Besides the fact that commands are run without a terminal (output and input is probably redirected to /dev/null), your command would also not run since what you're passing to at is not echo hello but just hello. Unless hello is really an existing command, it won't run. What you want probably is:
echo "echo hello" | at now + 1 minutes
If you want to know if your command is really running, try redirecting the output to a file:
echo "echo hello > /var/tmp/hello.out" | at now + 1 minutes
Check the file later.

Simple if statement in bash doesn't work

I am learning a little bit of bash in Linux and I just can't understand why this doesn't work. It is a simple IF statement and a read command to keep the window opened. What happens is that when I execute the .sh file the terminal's window opens for a second and closes back. I can't see any message or check whether there's any error or why it doesn't work. If I remove the IF block then I can see the message and the window remains opened. This is the code inside my file
count=99
if [ $count -eq 100 ]; then
echo "Count is 100"
else
echo "Count is not 100"
fi
read -p "Press enter to continue" nothing
I tried many other ways of using the IF structure but seems like none works
Use the dos2unix utility to convert the text file created on Windows to the correct format for Linux. See this wikipedia page for more details.
Install if necessary:
$ sudo apt-get install dos2unix
<snip>
Setting up dos2unix (5.3.1-1) ...
$
Run it on your script:
$ dos2unix if.sh
dos2unix: converting file if.sh to Unix format ...
$
Your script is completely correct. atleast its okai in my linux mint

Executing a command after the first command executed

I just recently installed beep on Ubuntu and finally managed to get it to work.
So I was able to hear the beeping sound after executing:
beep
Everything worked well, however, I was just wondering if it's possible to execute "beep" everytime I execute a command. Say for example:
cat /etc/passwd && beep
After reading /etc/passwd, it will be executing a beeping sound. I'd like to know if there's a way to execute beep after every command without having me to use "&& beep" always.
A clearer example:
ls && beep
ls -la && beep
cat /etc/passwd && beep
Notice the constant command "beep" followed by "&&" after every initial command.
You can set PROMPT_COMMAND=beep (try it first, then add to your ~/.bashrc if it doesn't drive you crazy). This will execute beep just before it displays the command prompt.
You could try altering your prompt:
PS1="$PS1"'\007'

Resources