1

Getting permission denied error while executing shell command from ruby console. And the same shell command is working from shell.

From Shell..

tests@tests-workstation:~$ "`grep '^datadir=' /etc/mysql/my.cnf | cut -f 2 -d '='`/db_backups"
bash: /db_backups: is a directory
tests@tests-workstation:~$

From ruby console..

>> %x["`grep '^datadir=' /etc/mysql/my.cnf | cut -f 2 -d '='`/db_backups"]
sh: /db_backups: Permission denied
=> ""

Any Idea !

1
  • Are you sure your example from the shell actually worked? bash: /db_backups: is a directory sure smells like an error message. What are you trying to accomplish? Why is the entire command in quotes? Commented Mar 28, 2011 at 5:56

2 Answers 2

3

You're trying to execute a directory and the shells are saying no; bash says no by saying "/db_backups: is a directory" whereas sh says "/db_backups: Permission denied". If you just execute the backedticked part:

grep '^datadir=' /etc/mysql/my.cnf | cut -f 2 -d '='

You'll almost certainly see no output at all and the reason is probably that your regular expression is too tight, something like this:

grep '^[  ]*datadir[  ]*=' /etc/mysql/my.cnf | cut -f2 -d'='

Would serve you better; the character classes contain a space and a tab.

Now that you're looking for the right things we can move on to why it still won't work. The %x[] quoter tries to execute its argument using the shell. When you feed the backticked grep stuff:

`grep '^[  ]*datadir[  ]*=' /etc/mysql/my.cnf | cut -f2 -d'='`/db_backups

to the shell, you should get a directory name that ends with /db_backups but you can't execute a directory. I think you want this to produce the directory name:

d = %x[echo `grep '^[  ]*datadir[  ]*=' /etc/mysql/my.cnf | cut -f2 -d'='`/db_backups].strip

Note the leading echo and the .strip call on the returned string. The .strip is necessary to remove the newline from what echo produces.

I think you're going through a lot of trouble for something that could easily be done with just a couple lines of Ruby:

dir = nil
File.open('/etc/mysql/my.cnf').each do |line|
    if(m = line.match(/^\s*datadir\s*=\s*(\S+)/))
        dir = m[1] + '/db_backups'
        break
    end
end

You could probably tighten that up a bit if you wanted but I think that that's at least less confusing than putting shell backticks inside Ruby backticks.

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

1 Comment

@sarnold: Thanks neighbor, West coast best coast.
0

It looks like you just want to get field 2 from the file. Then just do it in Ruby using split

File.open("file").each do |line|
   if line[/^datadir/] 
     print line.split("=",2)[0]
   end
end

There is no need to specifically shell out to call grep. This is inefficient and non-portable

Comments

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.