Dan
Dan

Reputation: 7744

Running commands in shell scripting

I have a very simple shell script which is meant to compile and run a .java file.

#!/bin/sh
x-terminal-emulator
javac SomeJavaFile.java
java SomeJavaFile

However this script seems to stop before it fires the Java commands. In essence the script may as well look like this

#!/bin/sh
x-terminal-emulator

How would I be able to fix this problem?

Edit

As per suggestions and answers my script now looks like this

#!/bin/sh
x-terminal-emulator -e "javac DropboxStatusLoop.java && java DropboxStatusLoop"

However it opens then closes instantly. I think this is strange since there is a loop going in my code.

Very simplistically, my code looks like this

import java.lang.*;

public class SomeJavaFile {
    public static void main(String[] args) {
        for(long i = 0; ; i++) {
            try {
                System.out.println("Hi");
                Thread.sleep(1000);
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}

It does compile and run properly when done manually, however, it has the same problem with the terminal opening and closing which was mentioned before. I believe this is because of Thread.sleep(1000); which may make the terminal think it has finished what it is doing so it stops and closes. Any help in fixing this is appreciated.

Upvotes: 0

Views: 481

Answers (2)

Matt C
Matt C

Reputation: 4555

Script fixes

This section highlights problems with the script itself, and does not touch on the bug with Linux that was also a problem. If you are reading this answer at a later date and you are only having problems with executing the script, see the below section "Bug fix for Linux, Nautilus users" or see this post.

  • The problem is that your script will run x-terminal-emulator which opens a new instance of a terminal, then it waits for that process to finish before continuing. There isn't anything that will make it finish though, it will just open and wait.

The Java compiling and running commands aren't passed to x-terminal-emulator, rather they are simply commands in your script that are executed after x-terminal-emulator finishes running.

  • Also, since you don't want to run the java program unless it successfully compiles, you should chain the commands together like this: command1 && command2. This way, command2 is only ran when command1 is successful.

To pass the Java commands to run in x-terminal-emulator, use the -e option like this:

x-terminal-emulator -e "javac SomeJavaFile.java && java SomeJavaFile"

This will send the commands to x-terminal-emulator.

  • Unless you specifically want to open another shell when this program runs, you most likely don't want to use x-terminal-emulator.

Simply remove that line from the script so the entire script becomes:

#!/bin/sh
javac SomeJavaFile.java
java SomeJavaFile
  • You must make sure that you have followed the steps to make your shell script executable, otherwise it must be ran from the terminal with the bash or sh command.

Making the script executable

To be able to run the script by double-clicking its icon, or by typing ./script.sh, you need to:

chmod +x script.sh

Where script.sh is the name of your script file.

chmod +x myScript.sh

And include the "she-bang" line at the top of your script file:

#!/bin/bash

Then you can double click its icon, or run it with ./myScript.sh.


Bug fix for Linux, Nautilus users

After finding the problems with the author's script, the solution still did not work because of a "bug" with Kali Linux, related to a bug with Nautilus in all Linux distributions.

To fix the bug, all of the steps in the "Making the script Executable" section have to be followed, as well as this next one.

What is the issue?

The default behavior of Kali Linux is to run executable shell scripts in the background, if they were clicked on (ran from the desktop or file explorer).

The default behavior of Nautilus, the default file explorer in most Linux distributions, is to open an executable shell script for editing when it is opened.

This explains why the author's script worked perfectly when they ran it from the terminal with ./script.sh or bash ./script.sh.

The fix

After following the steps in the section "Making the script Executable", you need to change a setting within Nautilus. This solution was found here, where it is talked about with more depth.

Here is the gist of the solution:

  • Open the file explorer, Nautilus, by opening any folder or typing nautilus. Then go to this menu:

     Edit → Preferences
    
  • Then go to the Behavior tab, and under Executable Text Files, select Ask each time. For non-Kali users, I do think that you can select Run executable text... as the default option.

Nautilus GUI showing where to find the "Ask Each Time" option

Kali must be configured to Ask each time an executable shell script opened, choosing "Run executable text files..." will not work! But, I do think that with other distributions you can choose "Run executable text files...." to be the default behavior.


Upvotes: 4

Mohammad Mahfooz Alam
Mohammad Mahfooz Alam

Reputation: 59

inside script, you are running a program "x-terminal-emulator" through script which is running in foreground. Hence it is not returning control to main script. Kindly remove that program from script if you just want to run java program through script.

#!/bin/sh
javac SomeJavaFile.java
java SomeJavaFile

Upvotes: 2

Related Questions