I was learning the command-line processing of bash shell. I understand the process of substituting the value for a common parameter like $para or ${para}. My question is what would be the processing order when string operator is involved. For example, if para is a variable preceded by a tab then followed by "string". It is known that ${para#\t} is meant to delete the preceding tab in para. So how is this processed by the shell? Is there any command substitution involved?
Can anyone give any hint? Thank you.
The Rundeck docs give the example of defining a message option (parameter) which can then be referred to by the script in a number of ways, including
echo message=#option.message# ;# replacement token
We use this syntax and it seems fine, but I have no idea what those two #s actually mean to bash; I can't find mention of anything beyond $#, or anything relevant for the "replacement token" in the comment.
Per the docs you linked, that is a "replacement token" handled by Rundeck. That is, Rundeck replaces the #...# before passing the command to bash. Consequently, they don't mean anything to bash :) . Specifically, the docs say:
Inline Script workflow steps that contain a token expansion will be expanded into a temporary file, and the temp file will contain the plaintext option value.
So bash sees the temp file post-expansion, without the #...# sequences and with their values as literal text.
The docs also note that "If the option is blank or unset the token will be replaced with a blank string." Therefore, the whole #...# sequence will disappear if a particular token is not defined.
See also this section on script usage and this section on context variables in the docs.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Example of what I want to combine:
sVar=$(whoami)
sVar=${sVar^}
sVar=${sVar::1}
Output:
Uppercase first character of username
Requirements:
One-liner
Do the rest of the processing with parameter substitutions except for the initial command substitution above $(whoami)
I realize this can be done with tr, sed, awk, printf, cut, etc.; but that is not the point of the question.
Any help is appreciate!
This isn't the real code or anything indicative of what I am wanting to actually do. I will often default (or try to) to using just one command over concatenating multiple commands.
I've seen other posts state that concatenating within the braces are not possible, but I know that everything is possible.
Please don't:
Reference other posts as duplicate that say it's impossible
One liner:
sVar=$(whoami) sVar=${sVar^} sVar=${sVar::1}
It may not be what you were looking for, but it is certainly a single command and uses parameter substitutions. A single command can consist of multiple variable assignments, in which case they are performed left to right.
The subject of a parameter substitution is a variable name, an indirection (a ! followed by a variable name), or a subscript expression (a variable name -- not an indirection -- followed by a subscript within [ and ]. That's a bit limited, to be sure, but that's bash. (Posix shell is even more restrictive; it has no indirection nor arrays, and fewer types of expansion.)
Posix wording from XCU, emphasis added:
When a given simple command is required to be executed… the following expansions, assignments, and redirections shall all be performed from the beginning of the command text to the end:
…
Each variable assignment shall be expanded for tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal prior to assigning the value.
This question already has answers here:
How to add a progress bar to a shell script?
(41 answers)
Closed 7 years ago.
I am thinking of writing a simple shell program that will show an output in the console about the percentage work completed.
something like thiss:-
2%==>
which will increase the arrow with respect to the work done.
I donot want to print the loader every time in a new line.
what should be my approach?'
*I often see this thing is used in wget and similar commands
TIA
To update the line the cursor is on, send a CR ("carriage return", \r) to send ("return") the cursor to the beginning of the existing line, from which you can print new contents. Contrast this to the newline (\n), which moves the cursor to a new line.
To see this in action, try running the following:
printf '%s\r' "Existing contents being written here"
sleep 1
printf '%s\r' "New contents being written here "
sleep 1
printf '%s\n' "Writing final contents and moving to a new line"
printf '%s\n' "This is written to a second line."
Note how the second line has some extra whitespace on the end; this padding is there to make sure that the end of the original line's contents are overwritten.
That said, if you just want a status bar already built for you, there are numerous solutions for that already:
pv (Pipe Viewer) will do all the math for you, including with large streams, binary streams, etc.
The dialog program contains a "gauge" widget, with similar functionality. See this example of its usage on Unix StackExchange.
I have a specific method for my bash prompt, let's say it looks like this:
CHAR="༇ "
my_function="
prompt=\" \[\$CHAR\]\"
echo -e \$prompt"
PS1="\$(${my_function}) \$ "
To explain the above, I'm builidng my bash prompt by executing a function stored in a string, which was a decision made as the result of this question. Let's pretend like it works fine, because it does, except when unicode characters get involved
I am trying to find the proper way to escape a unicode character, because right now it messes with the bash line length. An easy way to test if it's broken is to type a long command, execute it, press CTRL-R and type to find it, and then pressing CTRL-A CTRL-E to jump to the beginning / end of the line. If the text gets garbled then it's not working.
I have tried several things to properly escape the unicode character in the function string, but nothing seems to be working.
Special characters like this work:
COLOR_BLUE=$(tput sgr0 && tput setaf 6)
my_function="
prompt="\\[\$COLOR_BLUE\\] \"
echo -e \$prompt"
Which is the main reason I made the prompt a function string. That escape sequence does NOT mess with the line length, it's just the unicode character.
The \[...\] sequence says to ignore this part of the string completely, which is useful when your prompt contains a zero-length sequence, such as a control sequence which changes the text color or the title bar, say. But in this case, you are printing a character, so the length of it is not zero. Perhaps you could work around this by, say, using a no-op escape sequence to fool Bash into calculating the correct line length, but it sounds like that way lies madness.
The correct solution would be for the line length calculations in Bash to correctly grok UTF-8 (or whichever Unicode encoding it is that you are using). Uhm, have you tried without the \[...\] sequence?
Edit: The following implements the solution I propose in the comments below. The cursor position is saved, then two spaces are printed, outside of \[...\], then the cursor position is restored, and the Unicode character is printed on top of the two spaces. This assumes a fixed font width, with double width for the Unicode character.
PS1='\['"`tput sc`"'\] \['"`tput rc`"'༇ \] \$ '
At least in the OSX Terminal, Bash 3.2.17(1)-release, this passes cursory [sic] testing.
In the interest of transparency and legibility, I have ignored the requirement to have the prompt's functionality inside a function, and the color coding; this just changes the prompt to the character, space, dollar prompt, space. Adapt to suit your somewhat more complex needs.
#tripleee wins it, posting the final solution here because it's a pain to post code in comments:
CHAR="༇"
my_function="
prompt=\" \\[`tput sc`\\] \\[`tput rc`\\]\\[\$CHAR\\] \"
echo -e \$prompt"
PS1="\$(${my_function}) \$ "
The trick as pointed out in #tripleee's link is the use of the commands tput sc and tput rc which save and then restore the cursor position. The code is effectively saving the cursor position, printing two spaces for width, restoring the cursor position to before the spaces, then printing the special character so that the width of the line is from the two spaces, not the character.
(Not the answer to your problem, but some pointers and general experience related to your issue.)
I see the behaviour you describe about cmd-line editing (Ctrl-R, ... Cntrl-A Ctrl-E ...) all the time, even without unicode chars.
At one work-site, I spent the time to figure out the diff between the terminals interpretation of the TERM setting VS the TERM definition used by the OS (well, stty I suppose).
NOW, when I have this problem, I escape out of my current attempt to edit the line, bring the line up again, and then immediately go to the 'vi' mode, which opens the vi editor. (press just the 'v' char, right?). All the ease of use of a full-fledged session of vi; why go with less ;-)?
Looking again at your problem description, when you say
my_function="
prompt=\" \[\$CHAR\]\"
echo -e \$prompt"
That is just a string definition, right? and I'm assuming your simplifying the problem definition by assuming this is the output of your my_function. It seems very likely in the steps of creating the function definition, calling the function AND using the values returned are a lot of opportunities for shell-quoting to not work the way you want it to.
If you edit your question to include the my_function definition, and its complete use (reducing your function to just what is causing the problem), it may be easier for others to help with this too. Finally, do you use set -vx regularly? It can help show how/wnen/what of variable expansions, you may find something there.
Failing all of those, look at Orielly termcap & terminfo. You may need to look at the man page for your local systems stty and related cmds AND you may do well to look for user groups specific to you Linux system (I'm assuming you use a Linux variant).
I hope this helps.