Bash script execution in Mac os: directory not exists error - bash

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.

Related

command substitution not working in alias?

I wanted to make an alias for launching a vim session with all the c/header/makefiles, etc loaded into the buffer.
shopt -s extglob
alias vimc="files=$(ls -A *.?(c|h|mk|[1-9]) .gitconfig [mM]akefile 2>/dev/null); [[ -z $files ]] || vim $files"
When I run the command enclosed within the quotations from the shell, it works but when run as the alias itself, it does not. Running vimc, causes vim to launch only in the first matched file(which happens to be the Makefile) and the other files(names) are executed as commands for some reason(of course unsuccessfully). I tried fiddling around and it seems that the command substitution introduces the problem. Because running only the ls produces expected output.
I cannot use xargs with vim because it breaks the terminal display.
Can anyone explain what might be causing this ?
Here is some output:
$ ls
Makefile readme main.1 main.c header.h config.mk
$ vimc
main.1: command not found
main.c: command not found
.gitignore: command not found
header.h: command not found
config.mk: command not found
On an related note, would it be possible to do what I intend to do above in a "single line", i.e without storing it into a variable files and checking to see if it is empty, using only the output stream from ls?

SSH command chain does not work when put in single line

I have the following chain of commands which work perfectly well:
ssh Module
cd /MODULE_DIR/workspace/repository/
LATEST=`ls -tr *.snapshot | head -1`
mkdir fresh
cp ${LATEST} fresh
exit
I want to put this into a bash script:
ssh Module "cd /MODULE_DIR/workspace/repository/ && LATEST=`ls -tr *.snapshot | head -1` && mkdir fresh && cp \${LATEST} fresh"
But it outputs error:
ls: cannot access '*.snapshot': No such file or directory
cp: missing destination file operand after 'fresh'
Try 'cp --help' for more information.
What am I missing here?
Try using single quotes instead of double-quotes on your SSH command.
Bash's order of expansions is going to try to expand those variables inside the double quotes based on the variable assignments on the computer you're running it on.
The variables in your command are likely blank locally; you can test this by adding an echo before the first quote and have the server echo back what command it's receiving.
Wrapping it in a single quote should make your local terminal not try to expand that variable and let the box you're connecting to handle it.

csh doesn't recognize command with command line options beginning with --

I have an rsync command in my csh script like this:
#! /bin/csh -f
set source_dir = "blahDir/blahBlahDir"
set dest_dir = "foo/anotherFoo"
rsync -av --exclude=*.csv ${source_dir} ${dest_dir}
When I run this I get the following error:
rsync: No match.
If I remove the --exclude option it works. I wrote the equivalent script in bash and that works as expected
#/bin/bash -f
source_dir="blahDir/blahBlahDir"
dest_dir="foo/anotherFoo"
rsync -av --exclude=*.csv ${source_dir} ${dest_dir}
The problem is that this has to be done in csh only. Any ideas on how I can get his to work?
It's because csh is trying to expand --exclude=*.csv into a filename, and complaining because it cannot find a file matching that pattern.
You can get around this by enclosing the option in quotes:
rsynv -rv '--exclude=*.csv' ...
or escaping the asterisk:
rsynv -rv --exclude=\*.csv ...
This is a consequence of the way csh and bash differ in their default treatment of arguments with wildcards that don't match a file. csh will complain while bash will simply leave it alone.
You may think bash has chosen the better way but that's not necessarily so, as shown in the following transcript where you have a file matching the argument:
pax> touch -- '--file=xyzzy.csv' ; ls -- *.csv
--file=xyzzy.csv
pax> echo --file=*.csv
--file=xyzzy.csv
You can see there that the bash shell expands the argument rather than giving it to the program as is. Both sides have their pros and cons.

Execute command with backquote in bash shell script

I write up a little shell script in bash that allows me to execute commands in sub-directories. Here is the script
bat.sh:
#!/bin/sh
for d in */; do
echo "Executing \"$#\" in $d"
cd $d
`$#`
cd ..
done
With my following directory structures
/home/user
--a/
----x.txt
----y.txt
--b/
----u.txt
----v.txt
I expect the following command to list out the content of directories a and b when it is executed in the home directory
bat.sh ls
The result is
Executing "ls" in a/
/home/user/bin/bat.sh: line 6: x.txt: command not found
Executing "ls" in b/
/home/user/bin/bat.sh: line 6: u.txt: command not found
Any idea on what is going wrong here?
You don't want the back quotes; you want double quotes.
#!/bin/sh
for d in */
do
echo "Executing \"$*\" in $d"
(cd "$d" && "$#")
done
You are trying to execute the output of the command you pass, whereas you simply want to execute the command.
The use of an explicit subshell (the ( … ) notation) may avoid some problems with symlinks that jump to other directories. It is, in my (perhaps archaic) view, a safer way to switch directories for the purposes of executing commands.

Bash one liner: How to nest curly braces for list generation inside a curly brace command group?

The goal is to create a one line (copy and paste) bash command. The bash one line command should partition and format a drive, and when that results in a mountable volume, some initial maintenance commands.
The goal is to execute a list of commands when cd /Volumes/VolumeName succeeds in the current shell context. This grouping of commands can be done in bash by using curly braces. When cd /Volumes/VolumeName fails (echo $? != 0) further command execution is not necessary and command execution can stop.
The result of command cd /Volumes/$VOL && {sudo rm -fr .{,_.}{fseventsd,Spotlight-V100,Trashes}; mkdir .fseventsd;} is:
-bash: syntax error near unexpected token `}'
The bottleneck might be that one of the commands in the curly braced command list is using curly braces for list generation: sudo rm -fr .{,_.}{fseventsd,Spotlight-V100,Trashes}.
How to nest curly braces for list generation inside a curly brace command group?
You're just missing a necessary leading space. Consider:
mini:~ michael$ { echo sudo rm -fr .{,_.}{fseventsd,Spotlight-V100,Trashes}; echo mkdir .fseventsd;}
sudo rm -fr .fseventsd .Spotlight-V100 .Trashes ._.fseventsd ._.Spotlight-V100 ._.Trashes
mkdir .fseventsd
mini:~ michael$ {echo sudo rm -fr .{,_.}{fseventsd,Spotlight-V100,Trashes}; echo mkdir .fseventsd;}
-bash: syntax error near unexpected token `}'
If you look in man 1 bash under the Compound Commands section you'll see this (emphasis mine):
{ list; }
list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. Note that unlike the metacharacters ( and ), { and } are reserved words and must occur where a reserved word is permitted to be recognized. Since they do not cause a word break, they must be separated from list by whitespace.
Add spaces around braces that are used to command grouping. { sudo ... insead of {sudo ...
Maybe the problem is with the nested braces. Try with this:
cd /Volumes/$VOL && (sudo rm -fr .{,_.}{fseventsd,Spotlight-V100,Trashes}; mkdir .fseventsd;)
If you want to use a subshell, the rigth way is to use "()" instead of "{}".
Using "()" you don't need to add an extra space at the beginning of the command.

Resources