Re: check variable content size in sh script
I say this from a FreeBSD context. It may entirely be possible that a Linux distro uses bash in /bin/sh Yes. For most (all?) linux distros as well as osx, /bin/sh is actually bash. When I say emulation mode I mean running a script with a #!/bin/sh header on a system that doesn't have a real copy of sh. Whatever shell ends up running the script is effectively emulating sh's environment, at least in my mind. Bash is well known for not complaining when you use bash-specific features in a script which uses a #!/bin/sh header. This trips up many a programmer and causes script failures on systems where sh is not actually bash in disguise. This is why I question some things as to whether they're *really* valid pure sh syntax and not something that just happens to work in whatever shell is pretending to be sh (which I thought was tcsh on this machine I just did that test on, but on second look maybe not). __ it has a certain smooth-brained appeal ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On 05/18/2013 10:09 AM, Quartz wrote: However, if the OP wanted to actually truncate $FOO to 51 characters: NEWFOO=$( echo $FOO | awk -v max=51 '{print substr($0,0,max)}' ) You don't need all that for a simple truncation/substring, you can do it with a direct assignment: newfoo=${foo:0:51} That works for bash, not sh. -- Tim Daneliuk tun...@tundraware.com PGP Key: http://www.tundraware.com/PGP/ ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
However, if the OP wanted to actually truncate $FOO to 51 characters: NEWFOO=$( echo $FOO | awk -v max=51 '{print substr($0,0,max)}' ) You don't need all that for a simple truncation/substring, you can do it with a direct assignment: newfoo=${foo:0:51} The three params here are variable, start position and length. __ it has a certain smooth-brained appeal ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
newfoo=${foo:0:51} That works for bash, not sh. Ok granted, but I don't think that ${#foo} is straight sh either, so I assumed things bash/tcsh/ksh/whatever accept when running in sh emulation were ok. __ it has a certain smooth-brained appeal ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
#foo works with sh On May 18, 2013 10:58:30 AM Quartz qua...@sneakertech.com wrote: newfoo=${foo:0:51} That works for bash, not sh. Ok granted, but I don't think that ${#foo} is straight sh either, so I assumed things bash/tcsh/ksh/whatever accept when running in sh emulation were ok. __ it has a certain smooth-brained appeal ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On Sat, 18 May 2013 11:58:30 -0400, Quartz wrote: newfoo=${foo:0:51} That works for bash, not sh. Ok granted, but I don't think that ${#foo} is straight sh either, so I assumed things bash/tcsh/ksh/whatever accept when running in sh emulation were ok. By default, there is no bash on FreeBSD, and therefor no emulation and implicit features. :-) At least FreeBSD's implementation of sh (which is ash, I think) supports the # functionality. From man sh: ${#parameter} String Length. The length in characters of the value of parameter. And: ${parameter#word} Remove Smallest Prefix Pattern. The word is expanded to produce a pattern. The parameter expansion then results in parameter, with the smallest portion of the prefix matched by the pattern deleted. Check the chapter Parameter Expansion for more surprising things that are supported by ye olde /bin/sh. :-) -- Polytropon Magdeburg, Germany Happy FreeBSD user since 4.0 Andra moi ennepe, Mousa, ... ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On May 18, 2013, at 9:06 AM, Polytropon wrote: On Sat, 18 May 2013 11:58:30 -0400, Quartz wrote: newfoo=${foo:0:51} That works for bash, not sh. Ok granted, but I don't think that ${#foo} is straight sh either, so I assumed things bash/tcsh/ksh/whatever accept when running in sh emulation were ok. By default, there is no bash on FreeBSD, and therefor no emulation and implicit features. :-) At least FreeBSD's implementation of sh (which is ash, I think) dash actually -- the Debian Almquist shell (descendent of NetBSD's ash). -- Devin supports the # functionality. From man sh: ${#parameter} String Length. The length in characters of the value of parameter. And: ${parameter#word} Remove Smallest Prefix Pattern. The word is expanded to produce a pattern. The parameter expansion then results in parameter, with the smallest portion of the prefix matched by the pattern deleted. Check the chapter Parameter Expansion for more surprising things that are supported by ye olde /bin/sh. :-) -- Polytropon Magdeburg, Germany Happy FreeBSD user since 4.0 Andra moi ennepe, Mousa, ... ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org _ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
#foo works with sh Is it actually part of the official spec though is what I'm wondering, or is it a case of other shells not rejecting 'advanced' statements when running in emulation. At least FreeBSD's implementation of sh (which is ash, I think) supports the # functionality. The reason I say all this is that my copy of tcsh (on this not-freebsd machine) *doesn't* work with this when in sh emulation. __ it has a certain smooth-brained appeal ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
By default, there is no bash on FreeBSD, Right right... I know this, but forgot what list I was on :) It doesn't help that I always install bash first thing on any freebsd box or it get's installed automatically as part of pc-bsd anyway. __ it has a certain smooth-brained appeal ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On May 18, 2013, at 4:54 PM, Quartz wrote: #foo works with sh Is it actually part of the official spec though is what I'm wondering, or is it a case of other shells not rejecting 'advanced' statements when running in emulation. Shells don't have an emulation mode. The shell supports what it supports, and no shell that I've ever used had an emulation mode to act like another shell. Maybe you're referring to as emulation is actually the invocation line of the shell script. Make no mistake… when you change the invocation (first) line of a shell script from: #/bin/sh to: #/bin/tcsh You are not instructing a shell to emulate anything, you are actually using a different shell. sh != tcsh != bash != ash != dash != zsh Your script will use the shell that is written in the innovation line and the features you get are respective to which shell you choose. At least FreeBSD's implementation of sh (which is ash, I think) supports the # functionality. The reason I say all this is that my copy of tcsh (on this not-freebsd machine) *doesn't* work with this when in sh emulation. Get the idea that csh or tcsh are *anything* like sh out of your mind. Further, you almost *never* want to do any serious shell programming in csh or tcsh. Why? Because csh and tcsh have an incomplete programming spec. Most notably are the way that it handles pipe data and the standard-output/error file descriptors. Specifically, you cannot throw away stdout while keeping stderr. This short-coming may not be noticeable to all programmers that choose csh/tcsh, but if you want to do any serious programming, you'll eventually hit those limitations and be forced to move to a real shell (real in the sense that it has a complete programming specification). I personally never recommend csh/tcsh as a scripting language… but I can see the benefit that certain constructs (like repeat N cmd) have, purely for their simplicity (and readability for *very* short scripts). To challenge myself on this topic, I routinely try and cross-port very complex shell scripts to csh, and while I can do math with let and I can other things that a *normal* scripting language should allow… I invariably end up running away screaming in frustration. Again, csh != tcsh != sh != bash != ash != dash != zsh -- Devin _ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On May 18, 2013, at 5:06 PM, Teske, Devin wrote: On May 18, 2013, at 4:54 PM, Quartz wrote: #foo works with sh Is it actually part of the official spec though is what I'm wondering, or is it a case of other shells not rejecting 'advanced' statements when running in emulation. Shells don't have an emulation mode. The shell supports what it supports, and no shell that I've ever used had an emulation mode to act like another shell. I say this from a FreeBSD context. It may entirely be possible that a Linux distro uses bash in /bin/sh -- and it's entirely possible that bash may act differently if ARGV[0] is /bin/sh. But I wouldn't call this emulation. I'd call it standardization. When bash is invoked with an ARGV[0] of bash or {anything}/bash, it will act more like bash and less like standardized bourne shell, aka POSIX compliant /bin/sh (notice I didn't insert the name of any other shell, like ash, dash, etc. but instead I said like [a] standardized bourne shell. That is to say that bash will more strictly adhere to POSIX bourne shell standards when ARGV[0] is /bin/sh versus bash. Even when bash clamps down on the bash-specific features if/when ARGV[0] is /bin/sh… you still have access to constructs such as ${#foo}. All that being said… csh/tcsh has no such standards comliancy mode (what you called emulation). In fact… csh/tcsh don't follow the POSIX standards (or if it does… *extremely* loosely; see handling of file descriptors below in replied-to text). -- Devin Maybe you're referring to as emulation is actually the invocation line of the shell script. Make no mistake… when you change the invocation (first) line of a shell script from: #/bin/sh to: #/bin/tcsh You are not instructing a shell to emulate anything, you are actually using a different shell. sh != tcsh != bash != ash != dash != zsh Your script will use the shell that is written in the innovation line and the features you get are respective to which shell you choose. At least FreeBSD's implementation of sh (which is ash, I think) supports the # functionality. The reason I say all this is that my copy of tcsh (on this not-freebsd machine) *doesn't* work with this when in sh emulation. Get the idea that csh or tcsh are *anything* like sh out of your mind. Further, you almost *never* want to do any serious shell programming in csh or tcsh. Why? Because csh and tcsh have an incomplete programming spec. Most notably are the way that it handles pipe data and the standard-output/error file descriptors. Specifically, you cannot throw away stdout while keeping stderr. This short-coming may not be noticeable to all programmers that choose csh/tcsh, but if you want to do any serious programming, you'll eventually hit those limitations and be forced to move to a real shell (real in the sense that it has a complete programming specification). I personally never recommend csh/tcsh as a scripting language… but I can see the benefit that certain constructs (like repeat N cmd) have, purely for their simplicity (and readability for *very* short scripts). To challenge myself on this topic, I routinely try and cross-port very complex shell scripts to csh, and while I can do math with let and I can other things that a *normal* scripting language should allow… I invariably end up running away screaming in frustration. Again, csh != tcsh != sh != bash != ash != dash != zsh -- Devin _ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org _ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On 05/16/2013 10:08 AM, Joe wrote: Hello Have script that has max size on content in a variable. How to code size less than 51 characters? FOO=Some string you want to check length of FOOLEN=`echo $FOO | wc | awk '{print $3}'` You can then use $FOOLEN in a conditional. -- Tim Daneliuk tun...@tundraware.com PGP Key: http://www.tundraware.com/PGP/ ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
In the last episode (May 16), Tim Daneliuk said: On 05/16/2013 10:08 AM, Joe wrote: Hello Have script that has max size on content in a variable. How to code size less than 51 characters? FOO=Some string you want to check length of FOOLEN=`echo $FOO | wc | awk '{print $3}'` You can then use $FOOLEN in a conditional. Much better way: FOO=Some string you want to check length of FOOLEN=${#FOO} -- Dan Nelson dnel...@allantgroup.com ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
something like this: #!/bin/sh if [ $# -lt 1 ] ; then echo put a nickel in the slot, pal! exit 1; fi NUMCHARS=`echo $1 | wc -m` if [ $NUMCHARS -lt 51 ] ; then echo You input $NUMCHARS characters. exit 0 else echo whoa sailor I can't take all that! exit 1 fi On 13-05-16 9:08 AM, Joe wrote: Hello Have script that has max size on content in a variable. How to code size less than 51 characters? Thanks ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On May 16, 2013, at 8:28 AM, Tim Daneliuk wrote: On 05/16/2013 10:08 AM, Joe wrote: Hello Have script that has max size on content in a variable. How to code size less than 51 characters? FOO=Some string you want to check length of FOOLEN=`echo $FOO | wc | awk '{print $3}'` Uh, without forking to 2 separate programs… FOOLEN=${#FOO} You can then use $FOOLEN in a conditional. However, if the OP wanted to actually truncate $FOO to 51 characters: NEWFOO=$( echo $FOO | awk -v max=51 '{print substr($0,0,max)}' ) However, if you want to handle the case of $FOO containing newlines (and you want the newline to count toward the max), then this instead would do the trick: NEWFOO=$( echo $FOO | awk -v max=51 ' { len = length($0) max -= len print substr($0,0,(max 0 ? len : max + len)) if ( max 0 ) exit max-- }' ) $NEWFOO, even if multi-line, will be limited to 51-bytes (adjust max=51 accordingly for other desired-lengths). Newlines are preserved. Last, but not least, if you want to be able to handle multi-line values but only want to return the first line up-to N bytes (using 51 as the OP used): NEWFOO=$( echo $FOO | awk -v max=51 '{ print substr($0,0,max); exit }' ) If $FOO had multiple lines, $NEWFOO will have only the first line (and it will be truncated to 51 bytes or less). -- Devin _ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On 05/16/2013 10:45 AM, Dan Nelson wrote: In the last episode (May 16), Tim Daneliuk said: On 05/16/2013 10:08 AM, Joe wrote: Hello Have script that has max size on content in a variable. How to code size less than 51 characters? FOO=Some string you want to check length of FOOLEN=`echo $FOO | wc | awk '{print $3}'` You can then use $FOOLEN in a conditional. Much better way: FOO=Some string you want to check length of FOOLEN=${#FOO} D'Oh, you're right ... what was I thinking ... Slinks off in shame ... -- Tim Daneliuk tun...@tundraware.com PGP Key: http://www.tundraware.com/PGP/ ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On May 16, 2013, at 9:06 AM, Teske, Devin wrote: On May 16, 2013, at 8:28 AM, Tim Daneliuk wrote: On 05/16/2013 10:08 AM, Joe wrote: Hello Have script that has max size on content in a variable. How to code size less than 51 characters? FOO=Some string you want to check length of FOOLEN=`echo $FOO | wc | awk '{print $3}'` Uh, without forking to 2 separate programs… FOOLEN=${#FOO} You can then use $FOOLEN in a conditional. However, if the OP wanted to actually truncate $FOO to 51 characters: NEWFOO=$( echo $FOO | awk -v max=51 '{print substr($0,0,max)}' ) However, if you want to handle the case of $FOO containing newlines (and you want the newline to count toward the max), then this instead would do the trick: NEWFOO=$( echo $FOO | awk -v max=51 ' { len = length($0) max -= len print substr($0,0,(max 0 ? len : max + len)) if ( max 0 ) exit max-- }' ) For fun, I decided to expand on the solution I provided immediately above… turning it into a function that you might be a little more familiar with: snprintf() { local __var_to_set=$1 __size=$2 shift 2 # var_to_set/size eval $__var_to_set=\$\( printf \\$@\ \| awk -v max=\\$__size\ \'' { len = length($0) max -= len print substr($0,0,(max 0 ? len : max + len)) if ( max 0 ) exit max-- }'\' \) } Example usage: FOO=$( printf abc\n123\n ) snprintf NEWFOO 6 %s $FOO echo NEWFOO=[$NEWFOO] len=[${#NEWFOO}] Produces: NEWFOO=[abc 12] len=[6] Hopefully this should help some folks. -- Devin $NEWFOO, even if multi-line, will be limited to 51-bytes (adjust max=51 accordingly for other desired-lengths). Newlines are preserved. Last, but not least, if you want to be able to handle multi-line values but only want to return the first line up-to N bytes (using 51 as the OP used): NEWFOO=$( echo $FOO | awk -v max=51 '{ print substr($0,0,max); exit }' ) If $FOO had multiple lines, $NEWFOO will have only the first line (and it will be truncated to 51 bytes or less). -- Devin _ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: check variable content size in sh script
On May 16, 2013, at 9:27 AM, Teske, Devin wrote: On May 16, 2013, at 9:06 AM, Teske, Devin wrote: On May 16, 2013, at 8:28 AM, Tim Daneliuk wrote: On 05/16/2013 10:08 AM, Joe wrote: Hello Have script that has max size on content in a variable. How to code size less than 51 characters? FOO=Some string you want to check length of FOOLEN=`echo $FOO | wc | awk '{print $3}'` Uh, without forking to 2 separate programs… FOOLEN=${#FOO} You can then use $FOOLEN in a conditional. However, if the OP wanted to actually truncate $FOO to 51 characters: NEWFOO=$( echo $FOO | awk -v max=51 '{print substr($0,0,max)}' ) However, if you want to handle the case of $FOO containing newlines (and you want the newline to count toward the max), then this instead would do the trick: NEWFOO=$( echo $FOO | awk -v max=51 ' { len = length($0) max -= len print substr($0,0,(max 0 ? len : max + len)) if ( max 0 ) exit max-- }' ) For fun, I decided to expand on the solution I provided immediately above… turning it into a function that you might be a little more familiar with: snprintf() { local __var_to_set=$1 __size=$2 shift 2 # var_to_set/size eval $__var_to_set=\$\( printf \\$@\ \| awk -v max=\\$__size\ \'' { len = length($0) max -= len print substr($0,0,(max 0 ? len : max + len)) if ( max 0 ) exit max-- }'\' \) } Example usage: FOO=$( printf abc\n123\n ) snprintf NEWFOO 6 %s $FOO echo NEWFOO=[$NEWFOO] len=[${#NEWFOO}] Produces: NEWFOO=[abc 12] len=[6] Hopefully this should help some folks. I figured I'd help as many folks as I can… http://svnweb.freebsd.org/base?view=revisionrevision=250701 Added it to my string processing library. Lots of other useful functions in there. -- Cheers, Devin $NEWFOO, even if multi-line, will be limited to 51-bytes (adjust max=51 accordingly for other desired-lengths). Newlines are preserved. Last, but not least, if you want to be able to handle multi-line values but only want to return the first line up-to N bytes (using 51 as the OP used): NEWFOO=$( echo $FOO | awk -v max=51 '{ print substr($0,0,max); exit }' ) If $FOO had multiple lines, $NEWFOO will have only the first line (and it will be truncated to 51 bytes or less). -- Devin _ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org