Hello I am trying to write a Bash Script that will loop through a directory, and run the files in that directory through a command line program.
Unfortunately when I run it I keep getting
/home/user/Documents/Original_Files/*.fastq.gz: No such file or directory
Here's my code
Origin=/home/user/Documents/Original_Files/*.fastq.gz
for a in "$Origin"
do
BASE=basename "$a"
nohup java -jar $
done
Use an array if you want to keep several values in a variable.
Origin=(/home/user/Documents/Original_Files/*.fastq.gz)
for a in "${Origin[#]}" ; do
BASE=$(basename "$a")
nohup java -jar "$BASE"...
Related
I am creating a Dockerfile which starts a Java application. This Java application is given a file path which contains the output of ls -l.
(Note that in my real Dockerfile I am not doing ls - l but rather complex commands. I altered that to ls - l to simplify the question.)
I tried the following:
FROM openjdk:8-jre
ARG JAR
COPY target/$JAR /app/app.jar
CMD java -jar /app/app.jar <( ls -l )
This bash <( ... ) construction should create a temporary file containing the output of ls -l.
When starting the Docker file, I get:
/bin/sh: 1: Syntax error: "(" unexpected
Now, sh does not support the <( ... ) construction, hence the error. How can I start the application safely via bash instead of sh? With safely I mean that the Java app still will receive all OS signals (SIGHUP, ...) and react appropriately.
Replace your command with a JSON list, for which the first two elements are bash -c, and the last element is the shell command you actually want to run.
CMD ["bash", "-c", "exec java -jar /app/app.jar <( ls -l )"]
To generate such an array for a more complex command, you might consider using jq to ensure that syntax is correct, even for input with backslashes, newlines or quotes:
jq -cnRs '["bash", "-c", input]' <<'EOF'
# you can put other shell commands here if you need to
exec java -jar /app/app.jar <( ls -l )
EOF
exec ensures that the java instance replaces bash, and thus is sent signals directly.
If you're doing complex things on startup it's often easier to write them into a script than try to build a very complicated command line. Once you're doing that, you can use the set of primitives that are available in the POSIX shell standard, even if they require multiple commands to do things that GNU bash could do inline.
For this I might write a script:
#!/bin/sh
ls -l >/ls-l.txt
exec java -jar /app/app.jar /ls-l.txt
and then copy it in as the default thing your image runs
FROM openjdk:8-jre
ARG JAR
COPY target/$JAR /app/app.jar
COPY launch-app.sh /usr/bin/app
# RUN chmod +x /usr/bin/app, if it's not already executable
CMD ["app"]
I have the following bash script and it isn't quite working right. The objective here is to move XMLs from /source to /active folders, then call a java script and pass in XML file contents as argument, then move active file from /active to /archive folder.
Any help is greatly appreciated!
#!/bin/bash
JAVA_HOME=/usr/lib/jvm/jdk1.6.0_02
CLASSPATH=/tracking/lib/tracking_client.jar: .
FILES=/tracking/source/*
for f in $FILES
do
filename=$(basename "$f")
cd /tracking/source/
mv /tracking/source/${filename} /tracking/active/${filename}
cd /tracking/active/
$JAVA_HOME/bin/java -cp $CLASSPATH TrackClient ## need to pass XML file contents in to java call as argument
mv /tracking/active/${filename} /tracking/archive/${filename}
done
exit 0
Use $() to insert the result of a command into the command.
$JAVA_HOME/bin/java -cp $CLASSPATH TrackClient "$(cat "/tracking/active/${filename}")"
I have a directory with script files, say:
scripts/
foo.sh
script1.sh
test.sh
... etc
and would like to execute each script like:
$ ./scripts/foo.sh start
$ ./scripts/script1.sh start
etc
without needing to know all the script filenames.
Is there a way to append start to them and execute? I've tried tab-completion as it's pretty good in ZSH, using ./scripts/*[TAB] start with no luck, but I would imagine there's another way to do so, so it outputs:
$ ./scripts/foo.sh start ./scripts/script1.sh start
Or perhaps some other way to make it easier? I'd like to do so in the Terminal without an alias or function if possible, as these scripts are on a box I SSH to and shouldn't be modifying *._profile or .*rc files.
Use a simple loop:
for script in scripts/*.sh; do
"$script" start
done
There's just one caveat: if there are no such *.sh files, you will get an error. A simple workaround for that is to check if $script is actually a file (and executable):
for script in scripts/*.sh; do
[ -x "$script" ] && "$script" start
done
Note that this can be written on a single line, if that's what you're after for:
for script in scripts/*.sh; do [ -x "$script" ] && "$script" start; done
Zsh has some shorthand loops that bash doesn't:
for f (scripts/*.sh) "$f" start
I am using Cygwin Terminal to run shell to execute shell scripts of my Windows 7 system.
I am creating directory , but it is getting created with a dot in name.
test.sh
#!/bin/bash
echo "Hello World"
temp=$(date '+%d%m%Y')
dirName="Test_$temp"
dirPath=/cygdrive/c/MyFolder/"$dirName"
echo "$dirName"
echo "$dirPath"
mkdir -m 777 $dirPath
on executing sh test.sh its creating folder as Test_26062015 while expectation is Test_26062015.Why are these 3 special charterers coming , how can I correct it
Double quote the $dirPath in the last command and add -p to ignore mkdir failures when the directory already exists: mkdir -m 777 -p "$dirPath". Besides this, take care when combining variables and strings: dirName="Test_${temp}" looks better than dirName="Test_$temp".
Also, use this for static analysis of your scripts.
UPDATE: By analyzing the debug output of sh -x, the issue appeared due to DOS-style line-endings in the OP's script. Converting the file to UNIX format solved the problem.
I have a C program and a folder that contains files and I need to create a shell script that execute that C program and receives a file (one by one) name as argument which is read by the command line. How can I do this?
You could try the following shell code :
#!/bin/sh
cd /PATH/TO/DIR
for i in *; do./C_APP "$i"; done