how to pass a variable to system command in ruby? - ruby

In my ruby script I need to pass a file path to system command. For example, its like
system("run.exe -l C:\") where run.exe is my command and -l determines the local path.
Now if someone copies this to other machine drive C can be changed to drive E.
So my doubt is how to make it as a variable or how to take the current folder path in this.
Any suggestions are most welcome.

mu is too short and Jan give answers, but in general, you can put ruby commands in #{...} within "...". In this case, you can do:
system("fixed_string_1#{ruby_command_1}fixed_string_2#{ruby_command_2}fixed_string_3...")

You want to look at ARGF and ARGV

Related

Mistake this is a duplicate [duplicate]

This question already has answers here:
How to obtain the first letter in a Bash variable?
(7 answers)
Closed 3 years ago.
I am trying to my a custom terminal command. I just learned I am supposed to do it using the Unix script? I don't really know much of what that is and am still trying to figure it out. What I do know is that $1 is an arg is it possible to make it a variable and then get the first letter like you could in python?
EX:
str = 'happy'
str[0] = 'h'
You're asking a few different things here.
I am trying to my a custom terminal command.
That could mean a few different things, but the most obvious meaning is that you want to add an executable to your path so that when you type it at the terminal, it runs just like any other executable on your system. This requires just a few things:
the executable permission must be set.
the file must specify how it can be executed. For interpreted programs such as bash scripts or python scripts, you can do so by beginning the file with a "shebang line" that specifies the interpreter for the file.
the file must be in one of the locations specified by your $PATH.
I just learned I am supposed to do it using the Unix script?
there's no such thing as a "unix script", but what you seem to be referring to is a "shell script". Though these are commonly associated with unix, they're no more inherently a unix script than any other language. A shell, such as bash, sh, or any other, is just an interpreted language that is designed so that it is convenient to be used interactively by a human as well as being programmatically executed as part of a saved file.
I don't really know much of what that is and am still trying to figure it out.
Let's get into some specifics.
First I edit a file called 'hello-world' to contain:
#!/bin/bash
echo "Hello, world!"
Note that this filename has no "extension". Though heuristics based on file extension are sometimes used (espeically in windows) to determine a file type, unix typically sees a file "extension" as part of the arbitrary file name. The thing that makes this a potentially executable bash script is the specification of that interpreter on the shebang line.
We can run our script right now from bash, just as we could if we wrote a python script.
$ bash hello-world
hello, world!
To make the bash implicit, we mark the file as executable. This enables the linux operating system to consult the beginning "magic bytes" of the file to determine how to run it. Thes beginning bytes might signify an ELF file (a compiled executable, written in eg C, C++, or go). Or, it might be #! which just so happens means , "read the rest of this first line to determine the command to run, and pass the rest of this file into that command to be interpreted.
$ chmod +x hello-world
ls -l will show us the "permissions" on the file (more accurately called the "file mode", hence chmod rather than chperm) . The x stands for executable, so we have enabled the use of the leading bytes to determine method of execution. Remember, the first two bytes of this file, and the rest of that first line, then specify that this file should be "run through bash" so to speak.
$ ls -l hello-world
-rwxr-xr-x 1 danfarrell staff 33 Dec 27 20:02 hello-world
Now we can run the file from the current directory:
$ ./hello-world
hello, world!
At this point, the only difference between this command and any other on the system, is that you have to specify its location. That's because my current directory is not in the system path. In short, the path (accessible in a unix shell via the $PATH variable) specifies an ordered list of locations that should be searched for a specified command whose location is not otherwise specified.
For example, there's a very common program called whoami. I can run it directly from my terminal without specifying a location of the executable:
$ whoami
danfarrell
This is because there's a location in my $PATH in which the shell was able to find that command. Let's take a closer look. First, here's my path:
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin
And there's also a convenient program called whereis which can help show which path elements supply a named executable:
$ whereis whoami
/usr/bin/whoami
Sure enough, whoami is in one of the elements of the $PATH. (Actually I shared a simplified $PATH. Yours might be somewhat longer).
Finally, then, we can get to the last thing. If I put hello-world in one of the $PATH elements, I will be able to invoke it without a path. There are two ways to do this: we can move the executable to a location specified in the path, or we can add a new location to the path. For simplicity's sake I'll choose the first of these.
$ sudo cp hello-world /usr/local/bin/
Password:
I needed to use sudo to write to /usr/local/bin because it's not accessible as my user directly - that's quite standard.
Finally, I've achieved the goal of being able to run my very important program from any location, without specifying the executable's location.
$ hello-world
hello, world!
$ which hello-world
/usr/local/bin/hello-world
It works! I've created what might be described as a "custom terminal command".
What I do know is that $1 is an arg is it possible to make it a variable and then get the first letter like you could in python?
Well, one option would be to simply write the custom terminal command in python. If python is available,
$ which python
/usr/bin/python
You can specify it in a shebang just like a shell can be:
#!/usr/bin/env python
print("hello, world!"[0])
$ hello-world
h
it works!
Okay, confession time. I actually used #!/usr/bin/env python, not /usr/bin/python. env helps find the correct python to use in the user's environment, rather than hard coding one particular python. If you've been using python during the very long running python 2 to python 3 migration, you can no doubt understand why I"m reticent to hard code a python executable in my program.
It's certainly possible to get the first letter of a string in a bash script. But it's also very possible to write a custom command in a program other than shell. Python is an excellent choice for string manipulation, if you know it. I often use python for shell one-liners that need to interact with json, a format that doesn't lend itself well to standard unix tool stream editing.
Anyway, at the expense of incurring SO community's ire by reanswering an "already answered" question, I'll include a version in shell (Credit goes to David C Rankin)
#!/bin/bash
echo "${1:0:1}"
$ hello-world hiworld
h

What is the equivalent to locate command in KornShell?

I am using KornShell (ksh) and I need to know what is the command to search a file in the system?
I have used locate in bash looking for a similar one.
Kindly help.
You can use "find" command to search for a particular file in the system.
There are various option to search by name,size,time,etc
You can refer to man find for more help.
E.g.
find . -name abc
will search abc file in the current directory and subdirectories
locate is not a bash-internal command, it is an external program. Provided that /usr/bin/locate is installed and in your $PATH environment variable, it should work just the same in ksh.
Try
which cmdName
and/or
whence cmdName
where of course, you replace cmdName with the command you are searching for.
which1 will searchs the $PATH variable, whilewhence` (if available on your system) searchs $PATH, aliases and functions.
I hope this helps.
P.S. as you appear to be a new user, if you get an answer that helps you please remember to use the check mark to accept the answer, and/or give it a + (or -) as a useful answer.
old post but imho still important:
locate is not the same as find. locate keeps a database of filenames, in which it searches for the files. It is therefore faster but less up-to-date than find, which browses the actual directories on the fly.

Find out where an environment variable was last set in bash

Okay I know there is a bash debugger. But what I'm seeking is if I had an environment variable in one of my startup scripts and I don't know how it was set or where it might be, is there a way to find it other than exhaustively searching the scripts?
I mean is there a mechanism/tool that provides such a thing? Does bash keep track of variable setting locations?
Even though this might not seem very important but it crossed my mind the other day when I was helping a friend install OpenCL and the package supposedly set the variable $ATISTREAMSDKROOT automatically. Anyway the package was supposed to add a file to /etc/profile.d to allow for setting the variable, but it didn't. And luckily the variable came out blank.
But I was wondering if it hadn't come out blank, and the package added it to some random file, I would have probably had no way of telling where it is other than looking for it.
Of course I know one could write a sed command or two and search through the scripts but I'd consider that exhaustive search :D
One option would be to start an instance of bash with:
bash -x
... and look for where the variable is set in that output. To redirect that output to a file, you could do:
bash -x -ls -c "exit" 2> shell-startup-output
You should see in the output where each file is sourced.

Why ./script/generate is needed instead of script/generate in some Rails instruction?

Inside of Bash or Windows (or any other shell), is it needed to do
./script/generate scaffold foo name:string
instead of just using
script/generate ...
? I do see the first form sometimes, but the second form always works for me, on Mac OS X or Ubuntu, even if the PATH doesn't include the . (current directory)
So can the second form always work, so the first form is really not needed? I think for executable, we sometimes use ./a.out to run it... but seems like maybe script/generate doesn't need the ./ in front?
They mean exactly the same thing.
Starting from the current directory, select a subdirectory called 'script' and in it an executable called 'generate' and run it.
The difference is that with ./ you're explicitly specifying the current directory and without it, it's implicit.
There are 2 syntaxes of invocations in POSIX shell:
Running a program by specifying a name and then searching it in PATH enviornment variable - this one is used when program's name has no slashes (/).
Running a program by specifying full path to it manually - absolutely (path starting with /) or relatively (path starting with any other symbol). This one is chosen when program's name includes at least one / - thus it's a path, not just a name of file.
In your case, both ways to invoke - script/generate or ./script/generate are executed using variant #2 - by specifying a path to the program. ./ is an alias to current directory and in some cases it's required to be present (for example, when using cd command, you can't just say cd without argument and expect to change into current directory - cd reserves call without arguments to change to $HOME directory - but you may call cd ./ if you want to cd into current directory), but it's not required in this case of invocation.
you might want to have a look at 4 Ways of Executing a Shell Script and Shell Script Execution Guidlines. The main difference between both styles is:
script/generate ...
won't work if the parent directory of script does not lie in your current PATH environment. (Well this sure depends on how the shell's lookup method is implemented. There might be implementations that - to a last resort - are looking within your current working directory).
EDIT
Ok, I've done some research on this as I myself didn't seem to be knowing what the difference is. So, this is what I've arrived at:
The ./ (dot slash) syntax is an alias for the absolute path of the current working direcotry, so that - with e.g. /home/peter/script being the cwd -
peter#linux:/home/peter/script$./myscript
is expanded to /home/peter/script/myscript. The slash dot alias basically gives the shell a hint at where to find the executable/script.
That hint is what's essential, and that's the reason why
peter#linux:/home/peter$script/myscript
works as well whereas
peter#linux:/home/peter/script$myscript
won't. The former aids the shell in finding the right executable/script by providing some sort of reference point (namely the script directory). The latter, on the other hand, leaves the shell with a possibly ambiguous command, as there could be a homonymous script within the user's $PATH.
So, to come to an end, both of the styles you've asked the difference for do basically the same - giving the shell a hint at where to look for the executable/script. The shell then is able to unambiguously resolve the correct file and will happily execute it.
Have a nice day.
Nothing wrong with those answers except that they are too long - it's just about your PATH. If your path includes '.' then either way would workThat said, it's a bad habit to put '.' in your PATH for security reasons, so stick with './'

How can I reliably discover the full path of the Ruby executable?

I want to write a script, to be packaged into a gem, which will modify its parameters and then exec a new ruby process with the modified params. In other words, something similar to a shell script which modifies its params and then does an exec $SHELL $*. In order to do this, I need a robust way of discovering the path of the ruby executable which is executing the current script. I also need to get the full parameters passed to the current process - both the Ruby parameters and the script arguments.
The Rake source code does it like this:
RUBY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']).
sub(/.*\s.*/m, '"\&"')
If you want to check on linux: read files:
/proc/PID/exe
/proc/PID/cmdline
Other useful info can be found in /proc/PID dir
For the script parameters, of course, use ARGV.
File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])

Resources