krunal shah
krunal shah

Reputation: 16339

Executing shell command from ruby console returning Permission Denied Error?

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 !

Upvotes: 1

Views: 1257

Answers (2)

kurumi
kurumi

Reputation: 25599

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

Upvotes: 0

mu is too short
mu is too short

Reputation: 434635

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.

Upvotes: 3

Related Questions