# /bin/sh's function in chroot



## Seeker (Dec 3, 2013)

```
#!/bin/sh

say_whooot () {
    echo WHOOOT
}

/usr/sbin/chroot /poligon/freebsd /bin/sh -c 'say_whooot'
```

I 100% know why it doesn't work! I've already solved it by putting the function as string into a variable and passing it to `/bin/sh -c ...` What is the best and cleanest way to handle this?


----------



## sossego (Dec 3, 2013)

Clean code, proper formatting, constant/stable syntax, understanding and application of maths put in proper sequence. You just don't add anything unless it is necessary. This is my opinion.


----------



## ShelLuser (Dec 4, 2013)

Seeker said:
			
		

> I 100% know why it doesn't work! I've already solved it by putting the function as string into a variable and passing it to `/bin/sh -c ...` What is the best and cleanest way to handle this?


Handle what? I have a hard time understanding what it is you're trying to do here.

For the record I don't think the chroot aspect is the issue here. Even if you remove it you'll notice that your setup still won't work because /bin/sh doesn't seem to recognize the passed parameter.

Quite frankly I agree with @sossego here :h


----------



## fonz (Dec 4, 2013)

I gather that the OP wants to do a chroot and then exec a shell that executes whatever is in that function. To what end, I do not know. @Seeker, perhaps you can explain on a higher level (of abstraction) what it is you're actually trying to accomplish? The entire construct appears rather artificial to me.


----------



## sossego (Dec 4, 2013)

@Seeker is trying to emulate a text version of a speech program by entering the text as 

```
say==echo echo (") echo $VALUE echo (")
```
The term echo is proper for reason that numbers are not representation of sound. Numbers and symbols have a quantitative value while letters have a qualitative value.

@fonz, I am in agreement with you on it being artificial.  @Seeker, have you thought about using a graphical interface with a button labelled as "say" that connects to /bin/echo?  It's the repetition of the command that is strange.


----------



## Seeker (Dec 4, 2013)

ShelLuser said:
			
		

> Handle what? I have a hard time understanding what it is you're trying to do here.


Has anyone tried to run my code? If you did (/poligon/freebsd has a / binary FreeBSD install), you would get output:

```
say_whooot: not found
```
It should behave as:

```
#!/bin/sh

/usr/sbin/chroot /poligon/freebsd /bin/sh -c 'echo WHOOOT'
```
Which outputs *WHOOOT*

What does work is:

```
#!/bin/sh

function_in_var='say_whooot () {
    echo WHOOOT
}'

/usr/sbin/chroot /poligon/freebsd /bin/sh -c "$function_in_var; say_whooot"
```



			
				sossego said:
			
		

> @Seeker is trying to emulate a text version of a speech program by entering the text as
> 
> ```
> say==echo echo (") echo $VALUE echo (")
> ...


Jesus! It is unbelievable where have you gone in complexity over a simple basic problem, which doesn't have to do anything with original problem!  P

Back to the *true* topic. I don't like my working workaround. I want a cleaner way to do this.


----------



## kpa (Dec 4, 2013)

Assuming you'll be using only the /bin/sh shell that's about as elegant as it gets because there's no way to export function definitions in sh(1) the same way you can export environment variables. The shells/bash shell seems to have an extension `export -f` to do just that but I'm not sure if the exported functions would survive across the chroot(8) invocation.


----------



## ShelLuser (Dec 4, 2013)

Seeker said:
			
		

> Has anyone tried to run my code? If you did (/poligon/freebsd has a / binary FreeBSD install), you would get output:
> 
> ```
> say_whooot: not found
> ```


I have indeed, which made me wonder.

Now, on my system I don't have a /poligon/freebsd path and your message also doesn't make it clear if the script is in this directory. I assume as much considering the chroot being in place but alas. At first I set the directory to /home/peter/bin. Of course it doesn't really matter which location I use because the result is always the same, and one I somewhat expected:


```
root@smtp2:/home/peter/bin # ./test
chroot: /bin/sh: No such file or directory
```
After all; there is no /bin/sh in there.

So then I decided to point it to my jail, which does have a directory called /usr/bin:


```
/usr/sbin/chroot /usr/jails/dogma /bin/sh -c 'echo WHOOOT'
```
And that results in what you mentioned:


```
root@smtp2:/home/peter/bin # ./test
WHOOOT
```

*EDIT*:

That last test was with using an echo statement as -c parameter.

The problem, as @kpa hinted at, is simply that you're starting a new instance of sh and it will have no knowledge of any function in the script. After all, -c is said to be used for commands, and a function name isn't a command which can be used on the commandline. A snippet from sh(1):


```
The -c option causes the commands to be read from the string operand
     instead of from the standard input.  Keep in mind that this option only
     accepts a single string as its argument, hence multi-word strings must be
     quoted.
```


----------



## sossego (Dec 4, 2013)

@Seeker, there is no complexity in my statement. You are using the say{} function to replace what /bin/echo already does. My suggestion is to just keep /bin/echo as it is and use a graphical representation of say. I do not understand why one needs to add a Poettering type of complexity. Then again, I do not have the application installed for scripting as you do. Jesus had nothing to do with this, but my uncles Luis and Osvaldo did.


----------



## Seeker (Dec 5, 2013)

Ok, so as @kpa confirmed, this is the most elegant solution:

```
#!/bin/sh

function_in_var='say_whooot () {
    echo WHOOOT
}'

/usr/sbin/chroot /poligon/freebsd /bin/sh -c "$function_in_var; say_whooot"
```
Thread solved, unless someone provides superior code.  :beergrin


----------

