2

I want to test if a clearcase view exists and execute the remove command only if it exists. I am trying to do it from a shell script in a Linux 6.x environment. I tried to format my conditions both as one-liner as well as full "if" statement, but don't seem to be able to get it to work. What do I need to do to get both - one-liner and full if syntax - approaches working?

Here is the code, in its latest state

#!/bin/ksh
#
STREAMNAME=app_stream_int
PVOB=domain_pvob
VOB=domain_app

viewdir=/opt/local/software/rational/viewstorage
shareddir=/opt/shared/test
storagedir=${shareddir}/viewstorage
projectdir=${shareddir}/projects

ctdir=/opt/rational/clearcase/bin
viewname=$viewdir/test_$STREAMNAME.vws
viewtag=test_$STREAMNAME

echo "STREAMNAME $STREAMNAME - PVOB $PVOB - VOB $VOB"
echo "Removing View if it exists ... \n"

#  [ $(${ctdir}/cleartool lsview ${viewname}) ] && { ${ctdir}/cleartool rmview ${viewname}; echo "view removed" }

#  [ ${ctdir}/cleartool lsview -long ${viewtag} ] && { ${ctdir}/cleartool rmview ${viewname}; echo "view removed" }

#  ${ctdir}/cleartool lsview -long ${viewtag} | grep "Tag" && { ${ctdir}/cleartool rmview ${viewname}; echo "view removed" }

if [ ${ctdir}/cleartool lsview -long ${viewtag} | grep 'Tag' == "0" ]
then
    echo "view found"
    ${ctdir}/cleartool rmview ${viewname}
fi

I would prefer a one-liner type of solution, but 'if' statement will also work.

adbdkb
  • 1,897
  • 6
  • 37
  • 66
  • How about: `"${ctdir}/cleartool" lsview "${viewname}" >/dev/null 2>&1 && { "${ctdir}"/cleartool rmview "${viewname}"; echo "view removed"; }` – bishop Jun 17 '16 at 14:09
  • I shall try that. If I want to add a fail part to it indicating echo "Cannot remove view", how would I do that? Also, if possible, can you explain how this works? – adbdkb Jun 17 '16 at 14:23
  • Note: really removing a view involves untag and unregister: see nukeview in http://stackoverflow.com/a/4319090/6309. – VonC Jun 17 '16 at 15:26

1 Answers1

1

Provided the command follows the UNIX-convention of exit codes, the general one-liner looks like:

command && { success1; success2; } || { failure1; failure2; }

The list following && specifies what should run when command succeeds (exits with 0), while the list following || specifies what should run when the command fails. In the list, note that all the commands end in a semi-colon, including the last one.

For your specific case, this looks like it'll work:

"${ctdir}"/cleartool lsview "${viewname}" && { "${ctdir}"/cleartool rmview "${viewname}" && echo "view removed" || echo "cannot remove view"; }

Here is an example of this pattern in action, using standard commands:

$ ls foo && { rm -f foo && echo 'removed' || echo 'not removed'; }
ls: cannot access foo: No such file or directory

$ touch foo
$ ls foo && { rm -f foo && echo 'removed' || echo 'not removed'; }
foo
removed

$ sudo touch /foo
$ sudo chmod 600 /foo
$ ls /foo && { rm -f /foo && echo 'removed' || echo 'not removed'; }
/foo
rm: cannot remove ‘/foo’: Permission denied
not removed
bishop
  • 37,830
  • 11
  • 104
  • 139
  • Thanks again. In your earlier answer, what role did the part doing `" >/dev/null 2>&1 "` play in the evaluation of the "if" – adbdkb Jun 17 '16 at 15:19
  • @adbdkb both stdout and stderr are redirected to `/dev/null`, meaning they are ignored. The command `lsview` is only called for its exit value. 0 (ie the view exists) means the second part after `&&` is executed. 1 (the view does not exist) means the second part after `&&` is *not* executed. – VonC Jun 17 '16 at 15:28
  • `>/dev/null 2>&1` silenced output and errors. That was taking an unjustified liberty, so I removed it in this version. I still left the quotes around `${ctdir}`, in case that path ever has a space in it. – bishop Jun 17 '16 at 15:29
  • Thank you both for the explanations – adbdkb Jun 17 '16 at 16:02
  • One more query - If I want to break it upon 2 or more lines instead of one ling line, is it valid? Is there a continuation character I need to use? Sorry, should have added in the previous comment. – adbdkb Jun 17 '16 at 16:23
  • Use a backslash (`\ `) as the *last* character on the line, then continue on the next. Do *not* have any white space after the terminal backslash, or bash will fail with a syntax error. – bishop Jun 17 '16 at 16:26