Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Following is the script to copy all libraries of a certain command to make my chroot environment.

For example:

./cplb.sh /bin/ls will copy all the libraries of ls command (i.e., the files listed by ldd /bin/ls command).

cplb.sh

CHROOT='/var/chroot'
mkdir $CHROOT

for i in $( ldd $* |cut -d " " -f3 |sort |uniq)
do
cp --parents $i $CHROOT
done

echo "Chroot jail is ready. To access it execute: chroot $CHROOT"

Now, when I run ./cplb.sh /bin/ls it works like a charm. But when I run it for multiple commands at the same time, for example:

./cplb.sh /bin/{ls,cat}

it throws an error saying:

cannot stat : '/bin/ls:' file or dir not found
cannot stat : '/bin/cat:' file or dir not found

I can see a colon after the command, i.e., /bin/ls: and that colon causes the error. Now, where does it come from and how to resolve this, so that I can run the script for multiple commands at the same time?

share|improve this question
    
Try running ldd /bin/{ls,cat} from your prompt and see if you notice anything –  Wumpus Q. Wumbley Jul 21 '13 at 19:58

1 Answer 1

up vote 1 down vote accepted

This is what the output of ldd /bin/ls might look like:

linux-vdso.so.1 (0x00007fff2cffe000)
libcap.so.2 => /usr/lib/libcap.so.2 (0x00007f87e978f000)
libacl.so.1 => /usr/lib/libacl.so.1 (0x00007f87e9586000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f87e91d9000)
libattr.so.1 => /usr/lib/libattr.so.1 (0x00007f87e8fd4000)
/lib64/ld-linux-x86-64.so.2 (0x00007f87e9993000)

This is what the output of ldd /bin/ls /bin/cat might look like:

/bin/ls:
    linux-vdso.so.1 (0x00007fffd25df000)
    libcap.so.2 => /usr/lib/libcap.so.2 (0x00007f28f8d09000)
    libacl.so.1 => /usr/lib/libacl.so.1 (0x00007f28f8b00000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007f28f8753000)
    libattr.so.1 => /usr/lib/libattr.so.1 (0x00007f28f854e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f28f8f0d000)
/bin/cat:
    linux-vdso.so.1 (0x00007ffff9dfe000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007fc44208a000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fc442437000)

Try this instead:

ldd "$@" | cut -d' ' -f3 | sort -u | grep -v ':$' |
while read i
do
    cp --parents "$i" "$CHROOT"
done

Above, we use grep to remove the /bin/ls: and /bin/cat: lines. The :$ is a regular expression that matches colons at the ends of lines.

Note that I made a few other changes to your script. The piping-to-loop style is a bit more idiomatic. sort usually has a -u option to remove duplicates. It's generally preferable to use "$@" instead of $* as that will expand to filenames with spaces and special characters correctly. It shouldn't matter in this case though.


To copy both the commands and their libraries, add a second call to cp below the loop.

ldd "$@" | cut -d' ' -f3 | sort -u | grep -v ':$' |
while read i
do
    cp --parents "$i" "$CHROOT"
done
cp --parents "$@" "$CHROOT"
share|improve this answer
    
Hi Evan, Thank you so much. That worked like a charm. Maybe you could help me a little more. The script copies the libraries alone, whereas it doesn't copies the command itself. I mean, if i run the following command.. ./cplb.sh /bin/ls -- here it copies the libraries of ls, whereas it doesn't copy the command /bin/ls. I tried adding few lines to the actual script, the output of which is not as expected. Can you please tell me what should be added to the existing script so that it copies the command also. Thanks in advance. –  Being Gokul Jul 21 '13 at 21:49
    
@BeingGokul: You're welcome. I have appended instructions for copying both the commands and their libraries to my answer. –  paraxor Jul 21 '13 at 22:13
    
Hi Evan. Sorry to bug you again. Your suggestion would work when we run the script for more than 1 command. i.e., for example.... ./cplb.sh /bin/{ls,echo} because the output of "ldd /bin/{ls,echo}" includes both the command itself in it. But when we run the script just with one command. i.e) ./cplb.sh /bin/ls -- here the command won't be copied since the output of "ldd /bin/ls" doesn't include the command, but only libraries. Hope my question is clear. What could be done here? Thanks again. –  Being Gokul Jul 21 '13 at 23:21
    
@BeingGokul: I forgot about that. I have modified the bottom part of my answer to work in both situations. –  paraxor Jul 21 '13 at 23:27
    
Thank you so much. It works. –  Being Gokul Jul 22 '13 at 13:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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