0

I have a shell like (a short example just to make it simple)

#!/bin/sh
cat $1

I want to save as a file by doing something like

echo -e "#!/bin/sh" > test.sh
echo -e "cat $1" >> test.sh

the line contaning "#!/bin/sh" tries to interpret the line instead of writing it into a file and basically does some stange thing by getting older commands and print them to stdout

It is possible to achieve something?

PS: I tried something like "v=(cat << <some_file>); echo $v > test.sh" which works but again I am not able to replace the <some_file> using a string.

  • 1
    Use single quotes. `echo 'cat "$1"'` -- when you use double quotes teh `$1` gets replaced. – Charles Duffy Jul 26 '23 at 12:46
  • 1
    BTW, don't use the `-e` argument to `echo`. Most of the time it's not needed, and in the cases where it _is_ needed, the correct alternative is to use `printf '%b\n' "string"` instead of `echo -e "string"`. See [Why is printf better than echo?](https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo) on [unix.se], and the APPLICATION USAGE and RATIONALE sections of [the POSIX `echo` standard](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37) – Charles Duffy Jul 26 '23 at 12:50
  • (Really, read the standards document as a whole: a compliant `echo` isn't _allowed_ to take `-e` to mean anything but to mean "print -e on output", and while bash's is noncompliant by default, it _can_ be configured to comply with the standard, including complying with optional XSI extensions that make unescaping that `echo` otherwise enables the default; so unless you know exactly how your copy of bash is set up, you can never be quite sure what `echo` will do). – Charles Duffy Jul 26 '23 at 12:52
  • You have history-substitution in effect. You can turn it off with `set +H`. And, of course, the double-quotes in the `cat` line are silly, as Charles Duffy already explained. – user1934428 Jul 26 '23 at 13:04
  • I will try set +H, @Charles Duffy you did not answer my question, its not about discusssing -e option its about or about cat ist about how to echo #!/bin/sh in a file – MarkaRagnos0815 Jul 26 '23 at 16:39
  • the answer below it what i want – MarkaRagnos0815 Jul 26 '23 at 17:38
  • I know. If I were answering the questions instead of adding asides I would have used the "As an Answer" button, not comments. Answering the direct question is what answers are for, and asides and clarification requests are what comments are for. You'll notice that the duplicates I linked are mostly about history expansion. – Charles Duffy Jul 26 '23 at 17:47
  • @CharlesDuffy the problem is that I always get answers or hints I don't want. I am asking a specific question about echoing #!/bin/bash in a file. not about -e option. You don't know the background of this question which is much more than just echoing. I am aware of -e option AND I know it is available at target env. Its like I am asking a boost question and some comes up "why not use libX instead of boost". Just read the question and do not asume other hints or answer than the one asked for – MarkaRagnos0815 Jul 26 '23 at 18:15
  • You're welcome to ignore comments if they bother you -- but questions and their answers aren't just for the person who asked the question; we're building an educational resource here, a "long-tail FAQ" to quote one of Stack Overflow's founders. _You_ may not care if you're following nonportable practices, but _I_ care if I need to support someone who thought those practices were good ones to follow because they saw them go unchallenged in your post, and who then gets caught by the corner cases. (I care even more if I get hired somewhere you used to work and need to maintain your code). – Charles Duffy Jul 26 '23 at 19:17
  • Beyond that, practices become habits, and they transfer. If you're careful about following robust practices when there's no reason to think that it matters, that means you're also following those practices when it _does_ matter. Worst data loss event I've been present for happened in a situation where someone didn't bother to quote their variables because they "couldn't possibly" have unsafe values... until a buffer overflow happened in a C library used by a Python module, overwriting part of a variable used to form filenames and the thing that "couldn't" happen did. – Charles Duffy Jul 26 '23 at 19:22
  • @CharlesDuffy you don't understand the my point of view. First quoting with single quotes (plus docu) should be an answer from you and not a comment because this is the answer I am looking for, Second you don't know the users environment and circumstances either you ask before trolling or just ignore the question – MarkaRagnos0815 Jul 27 '23 at 07:12
  • On the first part, it would be inappropriate for me to add _any_ answer because the question is a duplicate and already has canonical answers on the prior instances. See the _Answer Well-Asked Questions_ section of [How to Answer](https://stackoverflow.com/help/how-to-answer), and the 3rd bullet point therein, setting down the rule that duplicative questions should not be answered. – Charles Duffy Jul 27 '23 at 16:37
  • On the second part, there are **no** circumstances where `echo -e "cat $1" >>test.sh` is correct code. Either you want to write `cat "$1"` to the file and so it should be `printf '%s\n' 'cat "$1"' >>test.sh` to the file, or you want to take the filename off `$1` and write _it_; but in that case you'd need to escape the filename to avoid injection attacks, so it would become something like `printf 'cat %q\n' "$1" >>test.sh` or `printf '%s\n' "cat ${1@Q}" >>test.sh` or so forth. – Charles Duffy Jul 27 '23 at 16:39
  • (to be clear, `echo -e "cat $1" >>test.sh` can _look_ correct if your goal is to read `$1` when you're writing `test.sh` and not when you're running it, _if_ you're supplying only test cases that don't handle the oddball corner cases, but as soon as you start looking for bugs it gets messy; consider if you want to write a script that always cats the file named `'/tmp/$(touch evil.txt)'$(touch evil.txt)'/hello` -- one _really does_ need `printf %q` or `${var@Q}` to dynamically perform correct escaping). – Charles Duffy Jul 27 '23 at 16:41
  • I've been in support forums for decades now, the #bash IRC channel before Stack Overflow existed, and I've had to handle bugs caused by people who are sloppy about these things; that's why one eventually tries to correct _all_ the practices shown, not just the ones the question is directly about, to avoid getting more questions from the same person down the line when they stick their foot on the next landmine; declining to show someone where the landmines in the language/tools they're using are is doing no favors long-term. – Charles Duffy Jul 27 '23 at 16:44

1 Answers1

2

You can escape the exclamation mark with a backslash, just like that:

echo -e "#\!/bin/bash" > test.sh
echo -e "cat $1" >> test.sh
artygo
  • 121
  • 5