How to configure triggers for specific users in IRSSI - perl

I'm not quite understanding the few examples for the irssi trigger.pl script, who's docs can be found here, on my Ubuntu machine (If that matters for irssi).
I'm trying to:
When a specific user foo joins a specific channel #channel , say 2 things in separate chat messages.
(Such as foo in message 1, and bar in message 2 as if I hit the enter key if I were typing it)
What I have so far:
/trigger add -name "channel_join_chat" -publics -channels "#channel" -joins "foo" -command "Foo" -command "bar"
And I'm not sure how to specify a specific user, as 'foo' is an unknown option to irssi.

I believe this is what you want:
/TRIGGER ADD -name "channel_join_chat" -joins -channels "#channel" -masks foo!*#* -command "Foo" -command "bar"
-publics should be when someone sends a PRIVMSG to a channel, so you want -joins to replace that for triggering on a JOIN (NOTE: it doesn't take a parameter which is why you get Unknown option: foo).
-masks is used to match users and wants a nick!ident#host mask, so to match the nick only, the mask would be foo!*#*.

Related

Weechat add hook command in every send Messages

I am a new user in Weechat. I have made a customized weechat script from another existing script. To run that script I need to use hook command every time i send text to channel . For example /myhook message_to_channel . I want to automate this process so every time I send messages to a channel i wouldn't need to write /myhook but just message_to_channel . Is there any way I could make it happen. Thanks.
The alias plugin that is included in WeeChat by default can facilitate this.
You can run the following command to create the alias you want.
/alias add message_to_channel /myhook message_to_channel
After that, you should be able to just use /message_to_channel. You can also add arguments if you like:
$n: argument 'n' (between 1 and 9)
$-m: arguments from 1 to 'm'
$n-: arguments from 'n' to last
$n-m: arguments from 'n' to 'm'
$*: all arguments
$~: last argument
$var: where "var" is a local variable of buffer (see /buffer localvar)
examples: $nick, $channel, $server, $plugin, $name
The documentation is here.

How can I pass unbound arguments from one script as parameters to another?

I have little experience with PowerShell in particular.
I'm trying to refactor some very commonly re-used code into a single script that can be sourced where it's needed, instead of copying and pasting this same code into n different scripts.
The scenario I'm trying to get looks (I think) like this:
#common.ps1:
param(
# Sure'd be great if clients didn't need to know about these
$some_params_here
...
)
function Common-Func-Uses-Params {
...
}
⋮
# foo/bar/bat.ps1:
# sure would love not to have to redefine all the common params() here...
. common.ps1 <pass-the-arguments>
Common-Func-Uses-Params $specific_Foo/Bar/Bat_Data
As the pseudo-comments above indicate, I've only been able to do this so far by capturing the params in the calling script as well.
I want to be in a situation where I can update the common code (say with a -Debug or -DryRun or -Url or whatever parameter) and not have to worry about updating all of the client code to match.
Is this possible?
You're missing two key things:
args - which captures all of (and only) the unbound arguments to the script
splatting (#) - which is used to pass arrays or hashtables to a command rather than flattening them like you'd get with $
When you combine these, you can easily pass all arguments onto another script, like so:
# foo.ps1
. common.ps1 #args
With a sourced file like this:
#common.ps1
param ([string]$foo = "foo")
echo "`$foo is $foo"
You get these output:
> foo.ps1 returns $foo is foo
> foo.ps1 -Foo bar returns $foo is bar
Note that, if you're trying to use the PowerShell ISE it might take you a while to figure this out or debug any of it. When you're in the debugger, both $args nor $MyInvocation.UnboundArguments will do their best to hide that information from you. They'll appear to be completely empty.
You can print the args with >> echo "$(#args)", but that also provides the very weird side effect of telling the Debugger to continue. I think the splatting is adding an extra newline and that's ending up in the Command Window.
The best workaround I have for that is to add $theargs = $args at the top of your script and remember to use $theargs in the debugger.

Manage inputs from external command in a powershell script

First, I would like to apologize in case that the title is not descriptive enough, I'm having a hard time dealing with this problem. I'm trying to build an automation for a svn merge using a powershell script that will be executed for another process. The function that I'm using looks like this:
function($target){
svn merge $target
}
Now, my problem occurs when there are conflicts in the merge. The default behavior of the command is request an input from the user and proceed accordingly. I would like to automatize this process using predefined values (show the differences and then postpone the merge), but I haven't found a way to do it. In summary, the workflow that I am looking to accomplish is the following:
Detect whether the command execution requires any input to proceed
Provide a default inputs (in my particular case "df" and then "p")
Is there any way to do this in powershell? Thank you so much in advance for any help/clue that you can provide me.
Edit:
To clarify my question: I would like to automatically provide a value when a command executed within a powershell script require it, like in the following example:
Requesting user input
Edit 2:
Here is a test using the snippet provided by #mklement0. Unfortunately, It didn't work as expected, but I thought it was wort to add this edition to clarify the question per complete
Expected behavior:
Actual result:
Note:
This answer does not solve the OP's problem, because the specific target utility, svn, apparently suppresses prompts when the process' stdin input isn't coming from a terminal (console).
For utilities that do still prompt, however, the solution below should work, within the constraints stated.
Generally, before attempting to simulate user input, it's worth investigating whether the target utility offers programmatic control over the behavior, via its command-line options, which is both simpler and more robust.
While it would be far from trivial to detect whether a given external command is prompting for user input:
you can blindly send the presumptive responses,
which assumes that no situational variations are needed (except if a particular calls happens not to prompt at all, in which case the input is ignored).
Let's assume the following batch file, foo.cmd, which puts up 2 prompts and echoes the input:
#echo off
echo begin
set /p "input1=prompt 1: "
echo [%input1%]
set /p "input2=prompt 2: "
echo [%input2%]
echo end
Now let's send responses one and two to that batch file:
C: PS> Set-Content tmp.txt -Value 'one', 'two'; ./foo.cmd '<' tmp.txt; Remove-Item tmp.txt
begin
prompt 1: one
[one]
prompt 2: two
[two]
end
Note:
For reasons unknown to me, the use of an intermediate file is necessary for this approach to work on Windows - 'one', 'two' | ./foo.cmd does not work.
Note how the < must be represented as '<' to ensure that it is passed through to cmd.exe and not interpreted by PowerShell up front (where < isn't supported).
By contrast, 'one', 'two' | ./foo does work on Unix platforms (PowerShell Core).
You can store the SVN command line output into a variable and parse through that and branch as you desire. Each line of output is stored into a new enumerator (cli output stored in PS variables is in array format)
$var = & svn merge $target
$var

how to get list of POSIX group members in Perl

Is there any way to get a list of all the members of a POSIX group in Perl?
I can't use getgrent() and similar because it returns the list as a space delimited string, and some usernames can have spaces in them.
I have to handle spaces in user and group names, because I'm working in an AD environment that other organizations can create users and groups in, so I'm trying to account for possible edge cases.
I'd say just use getgrent() and don't worry about spaces.
It may be possible to create a user name with one or more spaces in it, perhaps by manually editing /etc/passwd, but it's going to cause other problems as well. For example, ~foo is foo's home directory, but ~foo bar isn't foo bar's home directory.
On Linux, the useradd and adduser commands don't even permit spaces in file names. On Linux Mint 14 (based on Ubuntu 12.10):
$ sudo adduser 'foo bar'
adduser: To avoid problems, the username should consist only of
letters, digits, underscores, periods, at signs and dashes, and not start with
a dash (as defined by IEEE Std 1003.1-2001). For compatibility with Samba
machine accounts $ is also supported at the end of the username
$ sudo useradd !$
sudo useradd 'foo bar'
useradd: invalid user name 'foo bar'
$
Do you actually have user names with spaces on your system?
UPDATE: I've found that it actually is possible to create user names with spaces. useradd and adduser don't allow it (and you should be using one of those commands, or something similar, to create new accounts). But if I manually edit /etc/passwd using sudo vipw, I can create a user named foo bar, and I can do:
su - 'foo bar'
ssh 'foo bar#localhost'
etc. But it's a Really Bad Idea. Perl's getgr*() cannot tell whether a group contains one entry for foo bar or two entries for foo and bar (which is what you're asking about), and I can't use the shell's ~name syntax to refer to the account's home directory. I could use other methods to get both pieces of information, but it's much easier to avoid creating such an account in the first place.
If you're seriously concerned about some admin being foolish enough to create such an account, then you can use some of the alternative methods that have been discussed. But as I said, I don't think it's worth the effort.
(Perl could have avoided this problem by delimiting the list with : characters rather than spaces, since those are actually incompatible with the format of /etc/passwd and /etc/group, which the system depends on. But it's too late to change it now.)
UPDATE 2:
As you say in a comment (which I've edited into your question):
I have to handle spaces in user and group names, because I'm working in an AD environment that other organizations can create users and groups in, so I'm trying to account for possible edge cases.
Your solution from the same comment:
map((getgrgrid($_))[0], split(/ /, `id -G $username`))
is probably the best workaround. (id -G prints numeric group ids; which obviously can't contain spaces.)
It's probably also worth checking whether you actually have user or group names with spaces in them (though of course that doesn't guard against such names being added in the future). I wonder how your POSIX system actually deals with such names. I wouldn't be astonished if they're automatically translates them somehow. Even so, your id -G solution will still work.
If I have /etc/group:
...
postgres:x:26:
fsniper:x:481:
clamupdate:x:480:
some spacey group:x:482:saml, some spacey user
I can use the following commands to see this group's members:
% getent group
...
postgres:x:26:
fsniper:x:481:
clamupdate:x:480:
some spacey group:x:482:saml,some spacey user
Or if you know the specific group that you're interested in:
% getent group "some spacey group"
some spacey group:x:482:saml,some spacey user
These could be wrapped inside of a Perl script like this:
#!/usr/bin/perl
use feature qw(say);
chomp (my $getent = `getent group "some spacey group" | sed 's/.*://'`);
my #users = split(/,/, $getent);
foreach my $i (#users) { say $i; }
Running it:
% ./b.pl
saml
some spacey user
Resources
How to list all users in a Linux group?

How can I add color to the machine name in the prompt of a PowerShell Remoting session?

To make it more obvious when I'm remoted to a live/production server, I thought it'd be handy to be able to colour the machine name I'm connected to when using remote PowerShell sessions.
However, I can't see a way to do this... The server name prefix seems to be independent of the Prompt function, and even if I could use that, I'm not sure how I could define a new Prompt only for the duration of the session.
Is there a way to customise this? Note: I don't want to color all server names the same, I'd like a distinction between local/production servers.
After some searching around it seems like you are correct that there is not built-in hook to override the pre-prompt [computername]: tag.
Luckily, I have a hacky workaround which could work for you!
To get color, we can just use Write-Host. Write-Host output from the prompt function will be fully left-justified, which is what we want. Unfortunately, the default [computername]: tag is inserted directly afterward. That results in the computer name being duplicated in the prompt, once with color and once without.
We get around this by returning a string containing backspace characters, so the un-colored [computername]: will be overwritten. This is the normal prompt string, typically the current path.
Finally, in case the normal prompt string is short and does not fully overwrite the un-colored [computername]: tag, we need to do some final cleanup by adding dummy space characters. That might push out the caret, though, so we need to add more backspaces to return the caret to the corrent position.
All-up, use this on your remote machine:
# put your logic here for getting prompt color by machine name
function GetMachineColor($computerName)
{
[ConsoleColor]::Green
}
function GetComputerName
{
# if you want FQDN
$ipProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
"{0}.{1}" -f $ipProperties.HostName, $ipProperties.DomainName
# if you want host name only
# $env:computername
}
function prompt
{
$cn = GetComputerName
# write computer name with color
Write-Host "[${cn}]: " -Fore (GetMachineColor $cn) -NoNew
# generate regular prompt you would be showing
$defaultPrompt = "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
# generate backspaces to cover [computername]: pre-prompt printed by powershell
$backspaces = "`b" * ($cn.Length + 4)
# compute how much extra, if any, needs to be cleaned up at the end
$remainingChars = [Math]::Max(($cn.Length + 4) - $defaultPrompt.Length, 0)
$tail = (" " * $remainingChars) + ("`b" * $remainingChars)
"${backspaces}${defaultPrompt}${tail}"
}
I use Posh-Git to accomplish this. See their Prompt Customization. I noticed that some of the docs are a bit out of date, if you just type $GitPromptSettings in PowerShell you will see all the properties available. Using Posh-Git has the added bonus of seeing Git stats on the prompt.
The command I use to set the machine name is ...
$GitPromptSettings.DefaultPromptPrefix = '$(get-content env:computername) '
Here is the color setting
$GitPromptSettings.DefaultPromptPath.ForegroundColor = 'Orange'