0

I want to insert multiple lines into a Linux file at a specific location. But not from a Linux script, but remotely from a Windows batch file using PuTTY (with the plink command).

I looked into this answer here: https://stackoverflow.com/a/22497381

From that I created following Windows command that adds four "Hello" lines after "#SOMETAG" in "some.yml" file. This is working file:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/a Hello1\nHello2\nHello3\nHello4' ./some.yml

Now I saw that there exists a nice syntax in this answer here: https://stackoverflow.com/a/51585664

If I use this command here directly in an Ubuntu bash, it works file:

sed '/#SOMETAG/r'<(\
  echo "Hello1";\
  echo "Hello2";\
  echo "Hello3";\
  echo "Hello4";\
) -- ./some.yml

But how can I use this from Windows batch using plink?

Following approach did NOT work:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/r'<(\^
  echo "Hello1";\^
  echo "Hello2";\^
  echo "Hello3";\^
  echo "Hello4";\^
) -- ./some.yml

It produces the message "The system cannot find the file specified".

Even an easier version like this here produces the same error message:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/r'<(echo "Hello") -- ./some.yml

Can anybody help me?


EDIT 2019-08-29:

It is possible to just split the single line version contained at the beginning of my question into multiple lines escaped with ^:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/a^
Hello1\n^
Hello2\n^
Hello3\n^
Hello4^
' ./some.yml

But it is not a perfect solution, because indenting the "Hello" lines would produce leading blanks in the output (which I don't want to have). That's the reason why a solution based on https://stackoverflow.com/a/51585664 would be nice.

After the hint from MartinPrikryl that I forgot to escape the <, I made some additional tests with escaped < character.

The sample that is just adding one Hello line is working fine now:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/r'^<(echo "Hello") -- ./some.yml

But the other sample that is adding multiple Hello lines now produces the error "bash: -c: line 0: unexpected EOF while looking for matching `)'":

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/r'^<(\^
  echo "Hello1";\^
  echo "Hello2";\^
  echo "Hello3";\^
  echo "Hello4";\^
) -- ./some.yml
MaDev
  • 151
  • 9
  • 2
    At least the `<` is interpreted locally by Windows. You may need to escape it with `^` (not sure if it works though). – Martin Prikryl Aug 08 '19 at 20:06
  • @MartinPrikryl Thanks, this is a good hint. This was clearly an error in my command. The easy version containing only one echo is working fine now with this fix, but the more complicated version contaning two echos on multiple lines now produces another error message: `bash: -c: line 0: unexpected EOF while looking for matching ')'` `bash: -c: line 1: syntax error: unexpected end of file` – MaDev Aug 09 '19 at 07:54
  • Why do you put them to multiple lines? – Martin Prikryl Aug 09 '19 at 11:03
  • @MartinPrikryl Because I want to add six lines in the file. I thought it would be better understandable instead of using one very long line. – MaDev Aug 10 '19 at 13:20
  • OK, so can you try it first in a single line? And only once you make that working, try to make it readable? – Martin Prikryl Aug 10 '19 at 18:27
  • @MartinPrikryl The single line version is already contained at the beginning of my question. I will update my question with a sample where this single line is just splitted into multiple lines escaped with `^` ... – MaDev Aug 29 '19 at 11:53

2 Answers2

1

Did you consider/Is it acceptable to use -m to provide the command?

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer -m command.txt

With command.txt being:

sed '/#SOMETAG/r' <(
  echo "Hello1"
  echo "Hello2"
  echo "Hello3"
  echo "Hello4"
) -- ./some.yml

If you do not want an additional separate file, you can generate the command.txt by your batch.


Yet another option is to provide the input by local commands (of the batch file), like:

(
    echo Hello1
    echo Hello2
    echo Hello3
    echo Hello4
) | plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer "sed '/#SOMETAG/r' - ./some.yml"
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • That would also be a nice solution, but in my case I want to avoid having a separate `command.txt` file. But if it's not possible to fix the error I mentioned in my question ("bash: -c: line 0: unexpected EOF while looking for matching `)' "), I would mark this answer here as accepted... – MaDev Aug 29 '19 at 12:42
  • The last snippet unfortunately results in following error: `sed: -e expression #1, char 16: missing filename in r/R/w/W commands`. Anyway I set this answer to "accepted", because it also contains the sample with the `-m` argument, which I think is the best solution. – MaDev Sep 03 '19 at 07:14
  • I'm not getting that error. The `-` argument to `sed` should tell it to read stdin instead of a filename. Maybe you a have a diffrent version of `sed`. – Martin Prikryl Sep 03 '19 at 07:40
  • If it would work, it would be my favorite solution. I am using sed on Ubuntu 19.04 and `sed --version` says that I am using `sed (GNU sed) 4.7`. Which version are you using? – MaDev Sep 03 '19 at 15:51
  • I have "GNU sed version 4.2.1". – Martin Prikryl Sep 03 '19 at 16:00
0

you are specifying a relative path to the file but you can't know what the current directory (".") for the remote session is. Try specifying the complete path like "/home/me/some.yml"

greetings

Guess
  • 1