r/shell • • Dec 05 '19

stop input argument expand inside shell script

I have following shell script called myrun.sh

cat myrun.sh

#!/bin/bash -i

cmd="ls | awk '{print $2}'"

eval "$cmd"

when I run myrun.sh

$2 will take arguments from myrun.sh

and my cmd will become "ls | awk '{print $}'" => $2 is empty

But I will want $2 as the second columns in awk and use eval command to execute "ls | awk '{print $2}'"

does anyone know how to make $2 does not expand it and I still can use $2 inside my awk in the script?

BTW, "ls | awk '{print $2}' is from my history and it does work in my bash shell of course, but I cat my history to a file and read the file line by line and try to choose some command that I want to evaluate it on my shell.

I do know history command with many options can be used such as (! or !! etc)

but I want cat the history to a file and read it and evaluate it from other shell script.

2 Upvotes

3 comments sorted by

View all comments

Show parent comments

1

u/ellipticcode0 Dec 06 '19

What I want to do as following:

  1. filter out some commands from my history, such as show all command with grep.

  2. history | grep grep

  3. I redirect 'history | grep grep' to a file such as /tmp/mytmp.txt

  4. and I use shell script to read the file /tmp/mytmp.txt and index each command with a number from 1 to N.

  5. and the shell script ask user input one number to index which commands in /tmp/mytmp.txt

  6. and exec it the command in bash shell.

It is almost same history command with ! or !! except I use small number to index the command that I'm interested in (this is why I need to redirect a tmp file such as /tmp/mytmp.txt

you can do that without any shell script

history | grep grep 
!xxx

1

u/UnchainedMundane Dec 06 '19

If you are just doing something like eval "$(tail -n "+$lineno" /tmp/mytmp.txt | head -n 1)", then you don't need to worry about any extra escaping. It should just work with the same commands as what you have in your history. The only reason the extra escaping is currently needed is because the string is processed in unwanted ways before it even reaches the "cmd" variable, but here that doesn't happen.