First, although the wc
program is named for 'word count', wc -l
actually counts lines not words. I assume that is what you want even though it isn't what you said.
A shell pipline one | two | three
runs things in parallel with (only) their stdout and stdin connected; thus your command runs one subshell that changes directory to ~/path1
and immediately exits with no effect on anything else, and at the same time tries to run fgrep-f
(see below) in a different subshell which has not changed the directory and thus probably can't find any file, and in a third subshell does the assignment a= (see below) which also immediately exits so it cannot be used for anything.
You want to do things sequentially:
ssh u@h 'cd path1; fgrep -f abc.csv xyz.csv >par.csv; a=$(wc -l par.csv); if [ "$a" == "0" ] ...'
# you _might_ want to use && instead of ; so that if one command fails
# the subsequent ones aren't attempted (and possibly go further wrong)
Note several other important changes I made:
the command you give ssh
to send the remote must be in singlequotes '
not doublequotes "
if it contains any dollar as yours does (or backtick); with "
the $(wc ...)
is done in the local shell before sending the command to the remote
you don't need ~/
in ~/path1
because ssh
(or really sshd
) always starts in your home directory
there is no common command or program fgrep-f
; I assume you meant the program fgrep
with the flag -f
, which must be separated by a space. Also fgrep
although traditional is not standard (POSIX); grep -F
is preferred
you must have a space after [
and before ]
However, this won't do what you probably want. The value of $a
will be something like 0 par.csv
or 1 par.csv
or 999 par.csv
; it will never equal 0
so your "success" branch will never happen. In addition there's no need to do these in separate commands: if your actual goal is to check that there are no occurrences in xyz.csv of the (exact/non-regexp) strings in abc.csv both in path1, you can just do
ssh u@h 'if ! grep -qFf path1/abc.csv path1/xyz.csv; then echo success; fi'
# _this_ case would work with " instead of ' but easier to be consistent
grep
(always) sets its exit status to indicate whether it found anything or not; flag -q
tells it not to output any matches. So grep -q ...
just sets the status to true if it matched and false otherwise; using !
inverts this so that if grep
does not match anything, the then
clause is executed.
If you want the line count for something else as well, you can do it with a pipe
'a=$( fgrep -Ff path1/abc.csv path1/xyz.csv | wc -l ); if [ $a == 0 ] ...'
Not only does this avoid the temp file, when the input to wc
is stdin (here the pipe) and not a named file, it outputs only the number and no filename -- 999
rather than 999 par.csv
-- thus making the comparison work right.