1

I am running this command

awk '{print "Removing " ORS $0;system("rm " $0 ORS  " if [ $? -eq 0 ]" ORS "then" ORS "echo file  " $0 " has been removed." ORS "fi")}' <(cat /tmp/findo)

On bash and the command works however when executed from a shell script it throws the underlying error

Here is the example and you may look at the 'line 23 error'

# sh -x rvarlog_util.sh
+ findout=/tmp/findout
+ '[' -e /tmp/findout ']'
++ du -sm /var/log
++ awk '{print $1+0}'
+ cdu=2372
++ awk '{print $1+0}'
++ grep total
++ du -m --max-depth=1 -c -m -x /var/log/messages /var/log/messages-20190310 /var/log/messages-20190323-1553338190.gz /var/log/messages-20190324-1553424406.gz /var/log/messages-20190324-1553456095.gz /var/log/messages-20190324-1553456293.gz /var/log/messages-20190324-1553457237.gz /var/log/messages-20190324-1553457268.gz /var/log/maillog-20190324-1553456095.gz /var/log/boot.log /var/log/audit/audit.log /var/log/audit/audit.log-20190311-1552325090.gz /var/log/puppetlabs
+ fusage=2258
rvarlog_util.sh: line 23: syntax error near unexpected token `('
rvarlog_util.sh: line 23: `awk '{print "Removing " ORS $0;system("rm " $0 ORS  " if [ $? -eq 0 ]" ORS "then" ORS "echo file  " $0 " has been removed." ORS "fi")}' <(cat /tmp/findo)'
14
  • 2
    Please format your code properly. Commented Mar 25, 2019 at 12:13
  • awk '{print "Removing " ORS $0;system("rm " $0 ORS " if [ $? -eq 0 ]" ORS "then" ORS "echo file " $0 " has been removed." ORS "fi")}' <(cat /tmp/findout) is the command. Are you saying I should be formatting line 23 specifically? Commented Mar 25, 2019 at 12:16
  • See the link in my comment above for details of how to make your code above display correctly. Commented Mar 25, 2019 at 12:23
  • Sure, thank you . Let me format. Commented Mar 25, 2019 at 12:25
  • The problem is almost certainly on some earlier line of your shell script that you aren't showing us, e.g. a missing quote. Post a minimal reproducible example shell script that reproduces the error. Using shell to call awk to call system to call shell to call rm is a terrible idea btw - just call rm directly from shell. Commented Mar 25, 2019 at 12:38

2 Answers 2

3

@Ibraheem has the right solution, but so far nobody's spotted the problem. It's that you're using a process substitution (<(cat /tmp/findo)), but running the script with sh rather than bash. Process substitution isn't available in all shells (or even bash when it's invoked as "sh").

There are a couple of ways to fix this, and I'd recommend doing both ('cause they're good ideas on their own):

  • Don't use <(cat somefile), use a plain redirect, like <somefile. The process-substituted cat command is an overly complex, fragile, and inefficient way to read from a file.

  • Give the script a proper shebang line (#!/bin/bash or #!/usr/bin/env bash), make it executable (chmod +x rvarlog_util.sh), and run it directly by entering its path (./rvarlog_util.sh) rather than explicitly specifying a shell (sh or bash). In general, the script should "know" which shell it's written for, and overriding that (by explicitly specifying a shell when you run it) is a bad idea.

Sign up to request clarification or add additional context in comments.

2 Comments

Quite a few shells support <(command), actually, not just bash. (dash, used for /bin/sh on Debian, Ubuntu, and many other linux distributions isn't one of them, though.)
@Shawn Wow, I had no idea, but at least zsh and ksh 93 both support process substitution. I'll edit my answer to correct this.
2

from your awk command, what I understood that you are trying to remove files who's names found in /tmp/findo file, is that correct? then replace your awk command with below code and see if it works, BUT make sure that the file names in /tmp/findo contain absolute path to the required files you are trying to remove

while read -r files
do
  rm "$files" 
  if [ $? -eq 0 ] 
  then
     "echo $files has been removed."
  fi
done < /tmp/findo

4 Comments

I'd recommend double-quoting $files both times it's used (and for the echo command, double-quote the entire string). Also, you can simplify it by testing the result of rm directly: if rm "$files".
Or simpler: xargs -d'\n' rm -v </tmp/findo
@Wiimm this one liner does the job, thank you very much
@ronythomas welcome, you can accept the answer if that is all you needed,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.