1

I try to copy some files to given input.
Firstly I give an input in terminal like "*.txt".Then I have to send another .sh file

 read -p "Write input " input6
 bash ./prog.sh -R $input6

But ./prog.sh work wrong.,It gives an error :

cp: cannot stat '"*.txt"': No such file or directory"

If I write like this :

 bash ./prog.sh -R "*.txt"

works true.Files are copied.

What is the problem ? What do you think ? Any suggestions?

I don't understand what is the different $input6 and "*.txt" ?

I have to use menu.In order to run my program I send the commands to another .sh file.

By the way, my teacher wants to enter input with double quote like "*.txt"

  • Quote the variable `"$input6"` – Barmar Nov 18 '20 at 17:49
  • Although the script should receive the expansion of the wildcard as its arguments when you don't quote. It will only receive `*.txt` as the argument if there are no `.txt` files in the current directory. And in that case, it should act the same as if you quote the variable. So I don't think you should be getting that error message. – Barmar Nov 18 '20 at 17:51
  • This sounds like there is a quoting error in `prog.sh`. We can't see that code, so it's not really possible to tell you anything much more useful. See perhaps [When to wrap quotes around a shell variable](https://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable) – tripleee Nov 18 '20 at 18:04
  • @tripleee It can't be a quoting error there, because the wildcard will be expanded before passing the arguments to the script. – Barmar Nov 18 '20 at 18:12
  • This is closely related to [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050): *I'm trying to put a command in a variable, but the complex cases always fail!* -- as described there, and in the answer by Barmar, an unquoted expansion only goes through a limited subset of parsing steps; it doesn't behave the same way as having the same content in your code. That's a _good_ thing -- if data were magically treated as code you could never write secure code handling untrusted data. – Charles Duffy Nov 18 '20 at 18:15
  • Ohh true, I misread the diagnostics. – tripleee Nov 18 '20 at 18:18

2 Answers2

1

It sounds like you typed double quotes in your response to the prompt. You shouldn't do that, as quotes are not processed after expanding variables, so they'll be treated literally. Since you don't have any filenames beginning and ending with double quotes, the wildcard match will fail.

Instead, you should quote the variable when using it as the script argument.

bash ./prog.sh -R "$input6"

Then in response to the prompt just enter *.txt, not "*.txt".

If you're really required to enter double quotes, you need to use eval to process them.

eval "bash ./prog.sh -R $input6"

However, this is dangerous, because you can enter commands that will be executed by eval.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I tried 'bash ./prog.sh -R "$input6" but it didn't work. It gives an error again. --> "cp: cannot stat '"*.txt"': No such file or directory" –  Nov 18 '20 at 18:06
  • 2
    That's because `$input6` has quotes in it. I told you, don't type the quotes. – Barmar Nov 18 '20 at 18:09
  • This is related my hw and my teacher wants to enter input double quote like "*.txt" . So, I can't use *.txt. Even if I use like you said it gives the same error. But if I directly entered bash ./prog.sh -R "*.txt" it works. –  Nov 18 '20 at 18:25
  • I've updated the answer to show how to use `eval` to process double quotes. – Barmar Nov 18 '20 at 19:22
  • @codetime1, in `./prog.sh -R "*.txt"`, the quotes are removed **before** `prog.sh` is started -- they're instructions to the shell you typed the command into (telling it not to replace `*.txt` with a list of .txt files in your current directory), not part of the arguments that `prog.sh` receives. That's why if it's correct to have the quotes on the command line, it's _wrong_ to have those same quotes in a value you feed into `read`. – Charles Duffy Nov 18 '20 at 20:24
  • @codetime1 I suspect you may have misunderstood the instructions from the teacher. That's a very unusual requirement. – Barmar Nov 18 '20 at 21:09
  • Quotes are normally used in scripts, but not in user input. – Barmar Nov 18 '20 at 21:10
-1

This should take care of your problem:

read -p "Write input " input6

bash ./prog.sh -R $(echo $input6 | xargs)

P.S. I think that a better approach would be to disallow quotes inside the input string

Jonathan Jacobson
  • 1,441
  • 11
  • 20
  • 1
    `$(echo $anything | xargs)` is a _really_ bad idea. If `*.txt` includes a file named `two words.txt`, you'll be passing `two` and `words.txt` as separate arguments. It's also subject to all the problems described in [I just assigned a variable but `echo $variable` prints something else!](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else), and is otherwise creating more problems than it solves. And moreover, the OP wants to pass _the literal string_ `*.txt` to their program; this doesn't do that at all. – Charles Duffy Nov 18 '20 at 19:36
  • @CharlesDuffy I was sure that it was what the OP wanted. My bad. – Jonathan Jacobson Nov 18 '20 at 20:22
  • @CharlesDuffy It will, because `$input6` contains `"*.txt"`, which doesn't match anything, so it will be passed literally. But it would be better to use `echo "$input6"` or `printf '%s\n' "$input6"` – Barmar Nov 18 '20 at 20:40
  • @Barmar, xargs unquotes values when called without `-d` or `-0`; if given `"*.txt"`, it'll output `*.txt`, and so when the output of the command substitution is expanded unquoted onto `prog.sh`'s command line the glob will expand. – Charles Duffy Nov 18 '20 at 20:41
  • Oh, he needs to quote the command substitution, to prevent additional wildcard expression. – Barmar Nov 18 '20 at 20:49
  • `"$(echo "$input6" | xargs)"` – Barmar Nov 18 '20 at 20:49
  • @Barmar, ...exactly; only with those quotes are we passing `*.txt` as a literal string, as opposed to expanding it as a glob. – Charles Duffy Nov 18 '20 at 20:50