2

I am trying to edit my .bashrc file with a custom function to launch xwin. I want it to be able to open in multiple windows, so I decided to make a function that accepts 1 parameter: the display number. Here is my code:

function test(){
    a=$(($1-0))
    "xinit -- :$a -multiwindow -clipboard &"
}

The reason why I created a variable "a" to hold the input is because I suspected that the input was being read in as a string and not a number. I was hoping that taking the step where I subtract the input by 0 would convert the string into an integer, but I'm not actually sure if it will or not. Now, when I call

test 0

I am given the error

-bash: xinit -- :0 -multiwindow -clipboard &: command not found

How can I fix this? Thanks!

3
  • 1
    xinit -- ":$a" -multiwindow -clipboard & Commented Sep 23, 2015 at 17:17
  • 2
    If you quote it, bash will search for an executable named [[the whole thing with spaces and stuff]]. Commented Sep 23, 2015 at 17:18
  • 2
    a is still a string; bash doesn't have any other type. What it does do, however, is interpret strings as numbers when appropriate (such as inside $((...))). Just use $1 where you would use $a. Commented Sep 23, 2015 at 17:39

3 Answers 3

6

Because the entire quoted command is acting as the command itself:

$ "ls"
a b c
$ "ls -1"
-bash: ls -1: command not found

Get rid of the double quotation marks surrounding your xinit:

xinit -- ":$a" -multiwindow -clipboard &
Sign up to request clarification or add additional context in comments.

Comments

6

In addition to the double-quotes bishop pointed out, there are several other problems with this function:

  • test is a standard, and very important, command. Do not redefine it! If you do, you risk having some script (or sourced file, or whatever) run:

    if test $num -eq 5; then ...
    

    Which will fire off xinit on some random window number, then continue the script as if $num was equal to 5 (whether or not it actually is). This way lies madness.

  • As chepner pointed out in a comment, bash doesn't really have an integer type. To it, an integer is just a string that happens to contain only digits (and maybe a "-" at the front), so converting to integer is a non-opertation. But what you might want to do is check whether the parameter got left off. You can either check whether $1 is empty (e.g. if [[ -z "$1" ]]; then echo "Usage: ..." >&2 etc), or supply a default value with e.g. ${1:-0} (in this case, "0" is used as the default).

  • Finally, don't use the function keyword. bash tolerates it, but it's nonstandard and doesn't do anything useful.

So, here's what I get as the cleaned-up version of the function:

launchxwin() {
    xinit -- ":${1:-0}" -multiwindow -clipboard &
}

Comments

6

That happens because bash interprets everything inside quotes as a String. A command is an array of strings which the first element is a binary file or a internal shell command. Subsequent strings in the array are taken as argument.

When you type:

"xinit -- :$a -multiwindow -clipboard &"

the shell thinks that everything you wrote is a command. Depending on the command/program you ran all the rest of the arguments can be a single string. But mostly you use quotes only if you are passing a argument that has spaces inside like:

mkdir "My Documents"

That creates a single directory named My Documents. Also, you could escape spaces like this.

mkdir My\ Documents

But remember, "$" is a special character like "\". It gets interpreted by the shell as a variable. "$a" will be substituted by its value before executing. If you use a simple quote ('$a') it will not be interpreted by the shell.

Also, "&" is a special character that executes the command in background. You should probably pass it outside the quotes also.

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.