Here is a simple example showing that using declare in a script the script will not run, while sourcing the script will:

$ cat /tmp/new
#! /bin/sh
declare -i  hello
$ chmod a+rwx /tmp/new
$ /tmp/new
/tmp/new: 3: declare: not found
$ source /tmp/new

I wonder why directly running the script doesn't work, while sourcing it does? How can I make the first one work? Thanks!

4 Answers 4


declare is a builtin function and it's not available with /bin/sh, only with bash or zsh (and maybe other shells). The syntax may differ from one shell to another. You must choose your sheebang (#!) accordingly: if the script needs to be run by bash, the first line must be



#!/usr/bin/env bash

declare is a bash and zsh extension. On your system, /bin/sh is neither bash nor zsh (it's probably ash), so declare isn't available. You can use typeset instead of declare; they're synonyms, but typeset also works in ksh. In ash, there's no equivalent to typeset -i or most other uses of the typeset built-in. You don't actually need typeset -i to declare an integer variable; all it does is allow a few syntactic shortcuts like hello=2+2 for hello=$((2+2)).


declare probably doesn't exist in the shell defined by your shebang - #! /bin/sh.

Try #!/bin/bash instead.

The reason why sourcing it worked is that you were already in a shell that supports declare. Sourcing it didn't open a new shell thus didn't use the shebang that doesn't know declare.


You may also try the 2 other equivalent versions to Bash's declare, which are: typeset and local. They all work with -i (for integer). Also see my test script. PS. declare is not yet implemented in the Android (Mksh).

  • local works fine
    – Quanlong
    Jan 11, 2018 at 10:26
  • typeset will work for ksh Jan 21 at 18:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.