5

In Bash, I need an integer variable, like this:

declare -i n_jobs

to be assigned as a value the number of current background jobs:

jobs | wc -l

If I assign it as so:

n_jobs=$(jobs | wc -l)

is seems like a working integer, e.g.:

echo $((++n_jobs))

but... printing it (without running the increment above) reminds me that it contains blanks:

$ echo "$n_jobs"
$ <space><space><space><space><space>4

so I resort to this construct:

n_jobs=$(( $(jobs | wc -l) ))

to force immediate "casting" to int.

Is there a better way to take the output of a command substitution list and assign it to a variable as an integer?

6
  • 1
    The integer flag in bash is almost never used. Why do you actually care that it's set here? Commented Mar 24, 2013 at 23:41
  • Try $ echo $n_jobs Instead of $ echo "$n_jobs" Commented Mar 24, 2013 at 23:42
  • If the flag exists, it marks a variable as int, I know I want only int there, why would I not use what seems like a very convenient flag, designed exactly to express this condition? Commented Mar 24, 2013 at 23:42
  • Without specifying the integer flag, the spaces I mention appear.. it has its uses! Commented Mar 25, 2013 at 0:03
  • The only thing the integer attribute does is causes the RHS of an assignment to be evaluated as an arithmetic expression. It's not as useful as it sounds: x=7+9 works, but x=3*(7+9) still produces a syntax error and needs to be written as x=$(( 3*(7+9) )). A simple comment the first time you assign to a variable stating # n_jobs is an integer would work just as well. Also, I cannot reproduce the spaces you are observing. Commented Mar 25, 2013 at 0:08

2 Answers 2

4

Still bash-specific, but a cleaner way of getting a space-free integer might be:

job_pids=( $(jobs -p) )
n_jobs=${#job_pids[@]}

A POSIX-compliant version:

n_jobs=$( jobs -p | awk '{print NR}' )

(The -p isn't necessary, but you really don't need anything more than a unique line per job to feed to awk, so may as well make the lines as brief as possible.)

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

1 Comment

Whoa.. I like this one!
3

It's not really necessary, but you could do something like:

n_jobs=$(($n_jobs + 0))

Or

n_jobs=`expr $(jobs | wc -l)`

I would suggest that you actually avoid declare ... it exists in only one shell and it is not specified by Posix.

The shell is partly a macro processor and in its standardized form all variables are kept as strings. This is not a big handicap for jobs appropriate for the shell, and adding declare and integer variables makes bash only microscopically more suitable for complicated things.

Do those more complicated things in something like Ruby, Python, Perl, Go, or perhaps even something like node.js.

And by the way, I couldn't reproduce your original issue. When using declare -i, it does seem to evaluate your expression arithmetically and it does not seem to end up with any leading spaces.

declare -i qn_jobs
qn_jobs=$(jobs | wc -l)
echo "x$qn_jobs"
# => x0

7 Comments

Well, I am beginner, I forgot to mention that.
Sure, np. While I like bash for its nice interactive features and its incorporation of the csh ! history mechanism, it's way too complex to easily digest the manpage and learn shell programming. On Linux you may want to install dash, if for no other reason than to get a readable manpage. Here is another easy one with mostly-pure-Posix features: netbsd.gw.com/cgi-bin/man-cgi?sh++NetBSD-current (That's the shell dash is based on.)
Seriously? I had only heard little about "dash".. do you recommend it over Bash, even?
Yeah, if I do not put the -i in there.. I get the spaces! Try it and let me know if you see that too..
So, even if I got criticism in the comments for using -i it does actually serve that microscopic purpose, doesn't it? (I liked your use of "microscopic", as you can see) ;)
|

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.