Missing matching quote with su -c in bash script - bash

I want to write something like
EXEC="sudo su -m root -c \"java Something\""
$EXEC &
But i get the following error:
Something": -c: line 0: unexpected EOF while looking for matching `"'
Something": -c: line 1: syntax error: unexpected end of file
If I write the command on the command line it executes. If I have it stored in a variable and trying to extrapolate it - it does not. Why?

Try this:
exec="ls -l \"/a b c\""
$exec
You will see something like:
ls: cannot access "/a: No such file or directory
ls: cannot access b: No such file or directory
ls: cannot access c": No such file or directory
Which shows exactly where the problem is - that is - expansion of variable is done after word splitting.
To make it work, you can use eval:
=$ eval "$exec"
ls: cannot access /a b c: No such file or directory
or even:
=$ sh -c "$exec"
Or better yet, don't make such commands to run. Not sure what is the purpose of it, but think about avoiding building full command lines in variables.

Related

Why does the parallel command not work with backslashes when taking input from file?

Consider the following file saved as commands.txt
ls \
&& pwd
ls \
&& pwd
Now,
bash commands.txt
works as expected to give
LICENSE
/home/username/utilities
LICENSE
/home/username/utilities
but
parallel < commands.txt
gives the error
/bin/bash: -c: line 0: syntax error near unexpected token `&&'
/bin/bash: -c: line 0: `&& pwd'
ls: cannot access '\': No such file or directory
/bin/bash: -c: line 0: syntax error near unexpected token `&&'
/bin/bash: -c: line 0: `&& pwd
Why do multiple lines with the same command separated by \ not seem to work with parralel as such?
Why do multiple lines with the same command separated by \ not seem to work with parralel as such?
Because parallel does not parse \ and executes a separate shell for each line.
If your input has \n\n after each group (and only there), you can do:
cat commands.txt | parallel -d '\n\n'

Bash script execution in Mac os: directory not exists error

I have a command like this
bash -c 'cd \"/Users/Shammon/Projects/t2i-tokenisation-corda/build/nodes/AGCSIT\" ; \"/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/bin/java\" \"-Dcapsule.jvm.args=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5008 -javaagent:drivers/jolokia-jvm-1.6.0-agent.jar=port=7008,logHandlerClass=net.corda.node.JolokiaSlf4jAdapter\" \"-Dname=AGCSIT\" \"-jar\" \"/Users/Shammon/Projects/t2i-tokenisation-corda/build/nodes/AGCSIT/corda.jar\" && exit'
When I run this in match terminal, I am getting the following error
bash: line 0: cd:
"/Users/Shammon/Projects/t2i-tokenisation-corda/build/nodes/AGCSIT":
No such file or directory bash:
"/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/bin/java":
No such file or directory
But the paths are valid ones
Escaping the double quotes causes the shell to look treat them as literal parts of the filenames and parameters, instead of just it into a single token. There's no need to escape the quotes.
bash -c 'cd "/Users/Shammon/Projects/t2i-tokenisation-corda/build/nodes/AGCSIT" ; "/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/bin/java" "-Dcapsule.jvm.args=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5008 -javaagent:drivers/jolokia-jvm-1.6.0-agent.jar=port=7008,logHandlerClass=net.corda.node.JolokiaSlf4jAdapter" "-Dname=AGCSIT" "-jar" "/Users/Shammon/Projects/t2i-tokenisation-corda/build/nodes/AGCSIT/corda.jar"'
There's also no need for && exit at the end. When the command is done, the shell automatically exits.

Bash, excluding some file from the result of ls command, only by using the path

I would like to exclude some files from the output of an ls command.
As an example, I have these files :
[toto#damageinc ~]# ls -drt1 test_dir/*.txt
test_dir/FIXED-PATTERN1-RANDOM.txt
test_dir/FIXED-PATTERN2-RANDOM.txt
test_dir/FIXED-PATTERN3-RANDOM.txt
test_dir/FIXED-PATTERN4-RANDOM.txt
test_dir/FIXED-PATTERN5-RANDOM.txt
I want to exclude files containing PATTERN2 and PATTERN3 (extended globbing is set)
[toto#damageinc ~]# ls -drt1 test_dir/FIXED-!(PATTERN2|PATTERN3)-*.txt
test_dir/FIXED-PATTERN1-RANDOM.txt
test_dir/FIXED-PATTERN4-RANDOM.txt
test_dir/FIXED-PATTERN5-RANDOM.txt
Works fine.
The problem is that I do not execute the ls command myself and I cannot modify the way it is launched : sh -c "ls -drt1 path".
I just have access to "path", passed as a parameter to an executable (binary) containing this sh -c command
When I give the executable the path "test_dir/FIXED-!(PATTERN2|PATTERN3)-*.txt", I have this error :
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `ls -drt1 test_dir/FIXED-!(PATTERN2|PATTERN3)-*.txt'
Which is exactly the same when doing this by myself in the console :
[toto#damageinc ~]# sh -c 'ls -drt1 test_dir/FIXED-!(PATTERN2|PATTERN3)-*.txt'
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `ls -drt1 test_dir/FIXED-!(PATTERN2|PATTERN3)-*.txt'
How can have the correct result via sh -c, by modifying only my expression :
test_dir/FIXED-!(PATTERN2|PATTERN3)-*.txt
Thanks

Why do I get "syntax error near unexpected token `(' "?

I want to go through many directories and remove all the files except some that meet certain criterion. I have the following bash script:
#!/bin/bash
for i in */
do
cd $i
rm !(*M.*)
cd ..
done
However, when I run the script I get the following error:
script1.sh: line 5: syntax error near unexpected token `('
script1.sh: line 5: ` rm !(*M.*)'
What could be wrong? I'm using Ubuntu 14.04.
Thanks for your help.
I think you should enable extglob to use invert or negative wildcards:
shopt -s extglob
Note that you can keep this on all the time, it is not harmful.
That said, you are not forced to use a loop in your code and can directly put in your script:
rm */!(*M.*)
You can visit this post for other solutions:
https://unix.stackexchange.com/questions/78376/in-linux-how-to-delete-all-files-except-the-pattern-txt

Vowpal Wabbit command not found: No such file or directory

When I enter this command:
./vw -d click.train.vw -f click.model.vw --loss_function logistic
on cygwin I got this error:
-bash: ./vw: No such file or directory
I actually want to implement "PREDICTING CTR WITH ONLINE MACHINE LEARNING" website link for reference :
http://mlwave.com/predicting-click-through-rates-with-online-machine-learning/
Any help would be appreciated.
Answer based on common mistakes.
Execution by inexact name
Filename with blanks
Suppose you write ls in the command line and obtain the following:
$ ls
anyfile command
Then, you call your command with ./command and get the following:
$ ./command
bash: ./command: No such file or directory
Here you can think ls is wrong, but the actuality is that you can't easily recognize if a filename have, for example, leading or trailing spaces:
$ ls -Q # -Q, --quote-name -> enclose entry names in double quotes
"anyfile" "command "
As you see, here my command has a trailing space:
$ ./"command " # it works
Filename with extension
A common mistake is to call the command by the name without the extension (if any).
Let's name the command: command.sh:
$ ./command # wrong
$ ./command.sh # OK
Wrong file path
If you call your command with the prefix ./, it needs to be in your current directory ($PWD). If it is not, you will get:
$ ./command # relative path -> same as "$PWD/command"
bash: ./command: No such file or directory
In that case, you can try the following:
Executing the command by its absolute path
$ /home/user/command # absolute path (example). It starts with a slash (/).
Let the shell locate the command
If you provide just the command name without slashes, bash searches in each directory of the $PATH variable, for an executable file named command.
$ command
You can do that search with the which command:
$ which command
/usr/bin/command
If the search fails, you'll get comething like:
$ which unexistent_command
which: no unexistent_command in (/usr/local/sbin:/usr/local/bin:/usr/bin)
Broken link
Now, suppose you write ls -Q in the command line and obtain the following:
$ ls -Q
"anyfile" "command"
This time, you can be 100% secure command exists but when you try to execute it:
$ ./command
bash: ./command: No such file or directory
Reason? bash complains command doesn't exist, but what doesn't exist is the file command is pointing to by a Symbolic link. e.g.:
$ ls -l
total 0
-rw-r--r-- 1 user users 0 Jan 14 02:12 anyfile
lrwxrwxrwx 1 user users 27 Jan 14 02:12 command -> /usr/bin/unexistent_command
$ ls /usr/bin/unexistent_command
ls: cannot access /usr/bin/unexistent_command: No such file or directory
Notice that the following surely throw different errors that the one you are getting...
Execution permission
To execute a file, it must have the x bit activated. With ls -l you can check the file permission.
$ ls -l command
-rw-r--r-- 1 user users 0 Jan 3 19:52 command
In this case (it doesn't have the x bit activated), you can give permission with chmod:
$ chmod +x command
$ ls -l command
-rwxr-xr-x 1 user users 0 Jan 3 19:52 command

Resources