Compare commits
14 Commits
503e13aab7
...
1a95b3a24b
Author | SHA1 | Date |
---|---|---|
Tuxliban Torvalds | 1a95b3a24b | |
Tuxliban Torvalds | 53734d6262 | |
Tuxliban Torvalds | edef78f2ef | |
Tuxliban Torvalds | 795a0368ef | |
Tuxliban Torvalds | b41832192c | |
Tuxliban Torvalds | a4b5fcd301 | |
Tuxliban Torvalds | e705eb3b32 | |
Tuxliban Torvalds | 45b613748c | |
Tuxliban Torvalds | 7530d0ee22 | |
Tuxliban Torvalds | ea6890dd9f | |
Tuxliban Torvalds | f4101ebf22 | |
Tuxliban Torvalds | 84da58142e | |
Tuxliban Torvalds | de8ad312d8 | |
Tuxliban Torvalds | 0606b3484c |
|
@ -0,0 +1,816 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# This script is essentially copied from /usr/share/lintian/checks/scripts,
|
||||
# which is:
|
||||
# Copyright (C) 1998 Richard Braakman
|
||||
# Copyright (C) 2002 Josip Rodin
|
||||
# This version is
|
||||
# Copyright (C) 2003 Julian Gilbey
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long qw(:config bundling permute no_getopt_compat);
|
||||
use File::Temp qw/tempfile/;
|
||||
|
||||
sub init_hashes;
|
||||
|
||||
(my $progname = $0) =~ s|.*/||;
|
||||
|
||||
my $usage = <<"EOF";
|
||||
Usage: $progname [-n] [-f] [-x] [-e] script ...
|
||||
or: $progname --help
|
||||
or: $progname --version
|
||||
This script performs basic checks for the presence of bashisms
|
||||
in /bin/sh scripts and the lack of bashisms in /bin/bash ones.
|
||||
EOF
|
||||
|
||||
my $version = <<"EOF";
|
||||
This is $progname, from the Debian devscripts package, version 2.21.1
|
||||
This code is copyright 2003 by Julian Gilbey <jdg\@debian.org>,
|
||||
based on original code which is copyright 1998 by Richard Braakman
|
||||
and copyright 2002 by Josip Rodin.
|
||||
This program comes with ABSOLUTELY NO WARRANTY.
|
||||
You are free to redistribute this code under the terms of the
|
||||
GNU General Public License, version 2, or (at your option) any later version.
|
||||
EOF
|
||||
|
||||
my ($opt_echo, $opt_force, $opt_extra, $opt_posix, $opt_early_fail);
|
||||
my ($opt_help, $opt_version);
|
||||
my @filenames;
|
||||
|
||||
# Detect if STDIN is a pipe
|
||||
if (scalar(@ARGV) == 0 && (-p STDIN or -f STDIN)) {
|
||||
push(@ARGV, '-');
|
||||
}
|
||||
|
||||
##
|
||||
## handle command-line options
|
||||
##
|
||||
$opt_help = 1 if int(@ARGV) == 0;
|
||||
|
||||
GetOptions(
|
||||
"help|h" => \$opt_help,
|
||||
"version|v" => \$opt_version,
|
||||
"newline|n" => \$opt_echo,
|
||||
"force|f" => \$opt_force,
|
||||
"extra|x" => \$opt_extra,
|
||||
"posix|p" => \$opt_posix,
|
||||
"early-fail|e" => \$opt_early_fail,
|
||||
)
|
||||
or die
|
||||
"Usage: $progname [options] filelist\nRun $progname --help for more details\n";
|
||||
|
||||
if ($opt_help) { print $usage; exit 0; }
|
||||
if ($opt_version) { print $version; exit 0; }
|
||||
|
||||
$opt_echo = 1 if $opt_posix;
|
||||
|
||||
my $mode = 0;
|
||||
my $issues = 0;
|
||||
my $status = 0;
|
||||
my $makefile = 0;
|
||||
my (%bashisms, %string_bashisms, %singlequote_bashisms);
|
||||
|
||||
my $LEADIN
|
||||
= qr'(?:(?:^|[`&;(|{])\s*|(?:(?:if|elif|while)(?:\s+!)?|then|do|shell)\s+)';
|
||||
init_hashes;
|
||||
|
||||
my @bashisms_keys = sort keys %bashisms;
|
||||
my @string_bashisms_keys = sort keys %string_bashisms;
|
||||
my @singlequote_bashisms_keys = sort keys %singlequote_bashisms;
|
||||
|
||||
foreach my $filename (@ARGV) {
|
||||
my $check_lines_count = -1;
|
||||
|
||||
my $display_filename = $filename;
|
||||
|
||||
if ($filename eq '-') {
|
||||
my $tmp_fh;
|
||||
($tmp_fh, $filename)
|
||||
= tempfile("chkbashisms_tmp.XXXX", TMPDIR => 1, UNLINK => 1);
|
||||
while (my $line = <STDIN>) {
|
||||
print $tmp_fh $line;
|
||||
}
|
||||
close($tmp_fh);
|
||||
$display_filename = "(stdin)";
|
||||
}
|
||||
|
||||
if (!$opt_force) {
|
||||
$check_lines_count = script_is_evil_and_wrong($filename);
|
||||
}
|
||||
|
||||
if ($check_lines_count == 0 or $check_lines_count == 1) {
|
||||
warn
|
||||
"script $display_filename does not appear to be a /bin/sh script; skipping\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($check_lines_count != -1) {
|
||||
warn
|
||||
"script $display_filename appears to be a shell wrapper; only checking the first "
|
||||
. "$check_lines_count lines\n";
|
||||
}
|
||||
|
||||
unless (open C, '<', $filename) {
|
||||
warn "cannot open script $display_filename for reading: $!\n";
|
||||
$status |= 2;
|
||||
next;
|
||||
}
|
||||
|
||||
$issues = 0;
|
||||
$mode = 0;
|
||||
my $cat_string = "";
|
||||
my $cat_indented = 0;
|
||||
my $quote_string = "";
|
||||
my $last_continued = 0;
|
||||
my $continued = 0;
|
||||
my $found_rules = 0;
|
||||
my $buffered_orig_line = "";
|
||||
my $buffered_line = "";
|
||||
my %start_lines;
|
||||
|
||||
while (<C>) {
|
||||
next unless ($check_lines_count == -1 or $. <= $check_lines_count);
|
||||
|
||||
if ($. == 1) { # This should be an interpreter line
|
||||
if (m,^\#!\s*(?:\S+/env\s+)?(\S+),) {
|
||||
my $interpreter = $1;
|
||||
|
||||
if ($interpreter =~ m,(?:^|/)make$,) {
|
||||
init_hashes if !$makefile++;
|
||||
$makefile = 1;
|
||||
} else {
|
||||
init_hashes if $makefile--;
|
||||
$makefile = 0;
|
||||
}
|
||||
next if $opt_force;
|
||||
|
||||
if ($interpreter =~ m,(?:^|/)bash$,) {
|
||||
$mode = 1;
|
||||
} elsif ($interpreter !~ m,(?:^|/)(sh|dash|posh)$,) {
|
||||
### ksh/zsh?
|
||||
warn
|
||||
"script $display_filename does not appear to be a /bin/sh script; skipping\n";
|
||||
$status |= 2;
|
||||
last;
|
||||
}
|
||||
} else {
|
||||
warn
|
||||
"script $display_filename does not appear to have a \#! interpreter line;\nyou may get strange results\n";
|
||||
}
|
||||
}
|
||||
|
||||
chomp;
|
||||
my $orig_line = $_;
|
||||
|
||||
# We want to remove end-of-line comments, so need to skip
|
||||
# comments that appear inside balanced pairs
|
||||
# of single or double quotes
|
||||
|
||||
# Remove comments in the "quoted" part of a line that starts
|
||||
# in a quoted block? The problem is that we have no idea
|
||||
# whether the program interpreting the block treats the
|
||||
# quote character as part of the comment or as a quote
|
||||
# terminator. We err on the side of caution and assume it
|
||||
# will be treated as part of the comment.
|
||||
# s/^(?:.*?[^\\])?$quote_string(.*)$/$1/ if $quote_string ne "";
|
||||
|
||||
# skip comment lines
|
||||
if ( m,^\s*\#,
|
||||
&& $quote_string eq ''
|
||||
&& $buffered_line eq ''
|
||||
&& $cat_string eq '') {
|
||||
next;
|
||||
}
|
||||
|
||||
# Remove quoted strings so we can more easily ignore comments
|
||||
# inside them
|
||||
s/(^|[^\\](?:\\\\)*)\'(?:\\.|[^\\\'])+\'/$1''/g;
|
||||
s/(^|[^\\](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1""/g;
|
||||
|
||||
# If inside a quoted string, remove everything before the quote
|
||||
s/^.+?\'//
|
||||
if ($quote_string eq "'");
|
||||
s/^.+?[^\\]\"//
|
||||
if ($quote_string eq '"');
|
||||
|
||||
# If the remaining string contains what looks like a comment,
|
||||
# eat it. In either case, swap the unmodified script line
|
||||
# back in for processing.
|
||||
if (m/(?:^|[^[\\])[\s\&;\(\)](\#.*$)/) {
|
||||
$_ = $orig_line;
|
||||
s/\Q$1\E//; # eat comments
|
||||
} else {
|
||||
$_ = $orig_line;
|
||||
}
|
||||
|
||||
# Handle line continuation
|
||||
if (!$makefile && $cat_string eq '' && m/\\$/) {
|
||||
chop;
|
||||
$buffered_line .= $_;
|
||||
$buffered_orig_line .= $orig_line . "\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($buffered_line ne '') {
|
||||
$_ = $buffered_line . $_;
|
||||
$orig_line = $buffered_orig_line . $orig_line;
|
||||
$buffered_line = '';
|
||||
$buffered_orig_line = '';
|
||||
}
|
||||
|
||||
if ($makefile) {
|
||||
$last_continued = $continued;
|
||||
if (/[^\\]\\$/) {
|
||||
$continued = 1;
|
||||
} else {
|
||||
$continued = 0;
|
||||
}
|
||||
|
||||
# Don't match lines that look like a rule if we're in a
|
||||
# continuation line before the start of the rules
|
||||
if (/^[\w%-]+:+\s.*?;?(.*)$/
|
||||
and !($last_continued and !$found_rules)) {
|
||||
$found_rules = 1;
|
||||
$_ = $1 if $1;
|
||||
}
|
||||
|
||||
last
|
||||
if m%^\s*(override\s|export\s)?\s*SHELL\s*:?=\s*(/bin/)?bash\s*%;
|
||||
|
||||
# Remove "simple" target names
|
||||
s/^[\w%.-]+(?:\s+[\w%.-]+)*::?//;
|
||||
s/^\t//;
|
||||
s/(?<!\$)\$\((\w+)\)/\${$1}/g;
|
||||
s/(\$){2}/$1/g;
|
||||
s/^[\s\t]*[@-]{1,2}//;
|
||||
}
|
||||
|
||||
if (
|
||||
$cat_string ne ""
|
||||
&& (m/^\Q$cat_string\E$/
|
||||
|| ($cat_indented && m/^\t*\Q$cat_string\E$/))
|
||||
) {
|
||||
$cat_string = "";
|
||||
next;
|
||||
}
|
||||
my $within_another_shell = 0;
|
||||
if (m,(^|\s+)((/usr)?/bin/)?((b|d)?a|k|z|t?c)sh\s+-c\s*.+,) {
|
||||
$within_another_shell = 1;
|
||||
}
|
||||
# if cat_string is set, we are in a HERE document and need not
|
||||
# check for things
|
||||
if ($cat_string eq "" and !$within_another_shell) {
|
||||
my $found = 0;
|
||||
my $match = '';
|
||||
my $explanation = '';
|
||||
my $line = $_;
|
||||
|
||||
# Remove "" / '' as they clearly aren't quoted strings
|
||||
# and not considering them makes the matching easier
|
||||
$line =~ s/(^|[^\\])(\'\')+/$1/g;
|
||||
$line =~ s/(^|[^\\])(\"\")+/$1/g;
|
||||
|
||||
if ($quote_string ne "") {
|
||||
my $otherquote = ($quote_string eq "\"" ? "\'" : "\"");
|
||||
# Inside a quoted block
|
||||
if ($line =~ /(?:^|^.*?[^\\])$quote_string(.*)$/) {
|
||||
my $rest = $1;
|
||||
my $templine = $line;
|
||||
|
||||
# Remove quoted strings delimited with $otherquote
|
||||
$templine
|
||||
=~ s/(^|[^\\])$otherquote[^$quote_string]*?[^\\]$otherquote/$1/g;
|
||||
# Remove quotes that are themselves quoted
|
||||
# "a'b"
|
||||
$templine
|
||||
=~ s/(^|[^\\])$otherquote.*?$quote_string.*?[^\\]$otherquote/$1/g;
|
||||
# "\""
|
||||
$templine
|
||||
=~ s/(^|[^\\])$quote_string\\$quote_string$quote_string/$1/g;
|
||||
|
||||
# After all that, were there still any quotes left?
|
||||
my $count = () = $templine =~ /(^|[^\\])$quote_string/g;
|
||||
next if $count == 0;
|
||||
|
||||
$count = () = $rest =~ /(^|[^\\])$quote_string/g;
|
||||
if ($count % 2 == 0) {
|
||||
# Quoted block ends on this line
|
||||
# Ignore everything before the closing quote
|
||||
$line = $rest || '';
|
||||
$quote_string = "";
|
||||
} else {
|
||||
next;
|
||||
}
|
||||
} else {
|
||||
# Still inside the quoted block, skip this line
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
# Check even if we removed the end of a quoted block
|
||||
# in the previous check, as a single line can end one
|
||||
# block and begin another
|
||||
if ($quote_string eq "") {
|
||||
# Possible start of a quoted block
|
||||
for my $quote ("\"", "\'") {
|
||||
my $templine = $line;
|
||||
my $otherquote = ($quote eq "\"" ? "\'" : "\"");
|
||||
|
||||
# Remove balanced quotes and their content
|
||||
while (1) {
|
||||
my ($length_single, $length_double) = (0, 0);
|
||||
|
||||
# Determine which one would match first:
|
||||
if ($templine
|
||||
=~ m/(^.+?(?:^|[^\\\"](?:\\\\)*)\')[^\']*\'/) {
|
||||
$length_single = length($1);
|
||||
}
|
||||
if ($templine
|
||||
=~ m/(^.*?(?:^|[^\\\'](?:\\\\)*)\")(?:\\.|[^\\\"])+\"/
|
||||
) {
|
||||
$length_double = length($1);
|
||||
}
|
||||
|
||||
# Now simplify accordingly (shorter is preferred):
|
||||
if (
|
||||
$length_single != 0
|
||||
&& ( $length_single < $length_double
|
||||
|| $length_double == 0)
|
||||
) {
|
||||
$templine =~ s/(^|[^\\\"](?:\\\\)*)\'[^\']*\'/$1/;
|
||||
} elsif ($length_double != 0) {
|
||||
$templine
|
||||
=~ s/(^|[^\\\'](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1/;
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# Don't flag quotes that are themselves quoted
|
||||
# "a'b"
|
||||
$templine =~ s/$otherquote.*?$quote.*?$otherquote//g;
|
||||
# "\""
|
||||
$templine =~ s/(^|[^\\])$quote\\$quote$quote/$1/g;
|
||||
# \' or \"
|
||||
$templine =~ s/\\[\'\"]//g;
|
||||
my $count = () = $templine =~ /(^|(?!\\))$quote/g;
|
||||
|
||||
# If there's an odd number of non-escaped
|
||||
# quotes in the line it's almost certainly the
|
||||
# start of a quoted block.
|
||||
if ($count % 2 == 1) {
|
||||
$quote_string = $quote;
|
||||
$start_lines{'quote_string'} = $.;
|
||||
$line =~ s/^(.*)$quote.*$/$1/;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# since this test is ugly, I have to do it by itself
|
||||
# detect source (.) trying to pass args to the command it runs
|
||||
# The first expression weeds out '. "foo bar"'
|
||||
if ( not $found
|
||||
and not
|
||||
m/$LEADIN\.\s+(\"[^\"]+\"|\'[^\']+\'|\$\([^)]+\)+(?:\/[^\s;]+)?)\s*(\&|\||\d?>|<|;|\Z)/o
|
||||
and m/$LEADIN(\.\s+[^\s;\`:]+\s+([^\s;]+))/o) {
|
||||
if ($2 =~ /^(\&|\||\d?>|<)/) {
|
||||
# everything is ok
|
||||
;
|
||||
} else {
|
||||
$found = 1;
|
||||
$match = $1;
|
||||
$explanation = "sourced script with arguments";
|
||||
output_explanation($display_filename, $orig_line,
|
||||
$explanation);
|
||||
}
|
||||
}
|
||||
|
||||
# Remove "quoted quotes". They're likely to be inside
|
||||
# another pair of quotes; we're not interested in
|
||||
# them for their own sake and removing them makes finding
|
||||
# the limits of the outer pair far easier.
|
||||
$line =~ s/(^|[^\\\'\"])\"\'\"/$1/g;
|
||||
$line =~ s/(^|[^\\\'\"])\'\"\'/$1/g;
|
||||
|
||||
foreach my $re (@singlequote_bashisms_keys) {
|
||||
my $expl = $singlequote_bashisms{$re};
|
||||
if ($line =~ m/($re)/) {
|
||||
$found = 1;
|
||||
$match = $1;
|
||||
$explanation = $expl;
|
||||
output_explanation($display_filename, $orig_line,
|
||||
$explanation);
|
||||
}
|
||||
}
|
||||
|
||||
my $re = '(?<![\$\\\])\$\'[^\']+\'';
|
||||
if ($line =~ m/(.*)($re)/o) {
|
||||
my $count = () = $1 =~ /(^|[^\\])\'/g;
|
||||
if ($count % 2 == 0) {
|
||||
output_explanation($display_filename, $orig_line,
|
||||
q<$'...' should be "$(printf '...')">);
|
||||
}
|
||||
}
|
||||
|
||||
# $cat_line contains the version of the line we'll check
|
||||
# for heredoc delimiters later. Initially, remove any
|
||||
# spaces between << and the delimiter to make the following
|
||||
# updates to $cat_line easier. However, don't remove the
|
||||
# spaces if the delimiter starts with a -, as that changes
|
||||
# how the delimiter is searched.
|
||||
my $cat_line = $line;
|
||||
$cat_line =~ s/(<\<-?)\s+(?!-)/$1/g;
|
||||
|
||||
# Ignore anything inside single quotes; it could be an
|
||||
# argument to grep or the like.
|
||||
$line =~ s/(^|[^\\\"](?:\\\\)*)\'(?:\\.|[^\\\'])+\'/$1''/g;
|
||||
|
||||
# As above, with the exception that we don't remove the string
|
||||
# if the quote is immediately preceded by a < or a -, so we
|
||||
# can match "foo <<-?'xyz'" as a heredoc later
|
||||
# The check is a little more greedy than we'd like, but the
|
||||
# heredoc test itself will weed out any false positives
|
||||
$cat_line =~ s/(^|[^<\\\"-](?:\\\\)*)\'(?:\\.|[^\\\'])+\'/$1''/g;
|
||||
|
||||
$re = '(?<![\$\\\])\$\"[^\"]+\"';
|
||||
if ($line =~ m/(.*)($re)/o) {
|
||||
my $count = () = $1 =~ /(^|[^\\])\"/g;
|
||||
if ($count % 2 == 0) {
|
||||
output_explanation($display_filename, $orig_line,
|
||||
q<$"foo" should be eval_gettext "foo">);
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $re (@string_bashisms_keys) {
|
||||
my $expl = $string_bashisms{$re};
|
||||
if ($line =~ m/($re)/) {
|
||||
$found = 1;
|
||||
$match = $1;
|
||||
$explanation = $expl;
|
||||
output_explanation($display_filename, $orig_line,
|
||||
$explanation);
|
||||
}
|
||||
}
|
||||
|
||||
# We've checked for all the things we still want to notice in
|
||||
# double-quoted strings, so now remove those strings as well.
|
||||
$line =~ s/(^|[^\\\'](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1""/g;
|
||||
$cat_line =~ s/(^|[^<\\\'-](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1""/g;
|
||||
foreach my $re (@bashisms_keys) {
|
||||
my $expl = $bashisms{$re};
|
||||
if ($line =~ m/($re)/) {
|
||||
$found = 1;
|
||||
$match = $1;
|
||||
$explanation = $expl;
|
||||
output_explanation($display_filename, $orig_line,
|
||||
$explanation);
|
||||
}
|
||||
}
|
||||
# This check requires the value to be compared, which could
|
||||
# be done in the regex itself but requires "use re 'eval'".
|
||||
# So it's better done in its own
|
||||
if ($line =~ m/$LEADIN((?:exit|return)\s+(\d{3,}))/o && $2 > 255) {
|
||||
$explanation = 'exit|return status code greater than 255';
|
||||
output_explanation($display_filename, $orig_line,
|
||||
$explanation);
|
||||
}
|
||||
|
||||
# Only look for the beginning of a heredoc here, after we've
|
||||
# stripped out quoted material, to avoid false positives.
|
||||
if ($cat_line
|
||||
=~ m/(?:^|[^<])\<\<(\-?)\s*(?:(?!<|'|")((?:[^\s;>|]+(?:(?<=\\)[\s;>|])?)+)|[\'\"](.*?)[\'\"])/
|
||||
) {
|
||||
$cat_indented = ($1 && $1 eq '-') ? 1 : 0;
|
||||
my $quoted = defined($3);
|
||||
$cat_string = $quoted ? $3 : $2;
|
||||
unless ($quoted) {
|
||||
# Now strip backslashes. Keep the position of the
|
||||
# last match in a variable, as s/// resets it back
|
||||
# to undef, but we don't want that.
|
||||
my $pos = 0;
|
||||
pos($cat_string) = $pos;
|
||||
while ($cat_string =~ s/\G(.*?)\\/$1/) {
|
||||
# position += length of match + the character
|
||||
# that followed the backslash:
|
||||
$pos += length($1) + 1;
|
||||
pos($cat_string) = $pos;
|
||||
}
|
||||
}
|
||||
$start_lines{'cat_string'} = $.;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
warn
|
||||
"error: $display_filename: Unterminated heredoc found, EOF reached. Wanted: <$cat_string>, opened in line $start_lines{'cat_string'}\n"
|
||||
if ($cat_string ne '');
|
||||
warn
|
||||
"error: $display_filename: Unterminated quoted string found, EOF reached. Wanted: <$quote_string>, opened in line $start_lines{'quote_string'}\n"
|
||||
if ($quote_string ne '');
|
||||
warn "error: $display_filename: EOF reached while on line continuation.\n"
|
||||
if ($buffered_line ne '');
|
||||
|
||||
close C;
|
||||
|
||||
if ($mode && !$issues) {
|
||||
warn "could not find any possible bashisms in bash script $filename\n";
|
||||
$status |= 4;
|
||||
}
|
||||
}
|
||||
|
||||
exit $status;
|
||||
|
||||
sub output_explanation {
|
||||
my ($filename, $line, $explanation) = @_;
|
||||
|
||||
if ($mode) {
|
||||
# When examining a bash script, just flag that there are indeed
|
||||
# bashisms present
|
||||
$issues = 1;
|
||||
} else {
|
||||
warn "possible bashism in $filename line $. ($explanation):\n$line\n";
|
||||
if ($opt_early_fail) {
|
||||
exit 1;
|
||||
}
|
||||
$status |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Returns non-zero if the given file is not actually a shell script,
|
||||
# just looks like one.
|
||||
sub script_is_evil_and_wrong {
|
||||
my ($filename) = @_;
|
||||
my $ret = -1;
|
||||
# lintian's version of this function aborts if the file
|
||||
# can't be opened, but we simply return as the next
|
||||
# test in the calling code handles reporting the error
|
||||
# itself
|
||||
open(IN, '<', $filename) or return $ret;
|
||||
my $i = 0;
|
||||
my $var = "0";
|
||||
my $backgrounded = 0;
|
||||
local $_;
|
||||
while (<IN>) {
|
||||
chomp;
|
||||
next if /^#/o;
|
||||
next if /^$/o;
|
||||
last if (++$i > 55);
|
||||
if (
|
||||
m~
|
||||
# the exec should either be "eval"ed or a new statement
|
||||
(^\s*|\beval\s*[\'\"]|(;|&&|\b(then|else))\s*)
|
||||
|
||||
# eat anything between the exec and $0
|
||||
exec\s*.+\s*
|
||||
|
||||
# optionally quoted executable name (via $0)
|
||||
.?\$$var.?\s*
|
||||
|
||||
# optional "end of options" indicator
|
||||
(--\s*)?
|
||||
|
||||
# Match expressions of the form '${1+$@}', '${1:+"$@"',
|
||||
# '"${1+$@', "$@", etc where the quotes (before the dollar
|
||||
# sign(s)) are optional and the second (or only if the $1
|
||||
# clause is omitted) parameter may be $@ or $*.
|
||||
#
|
||||
# Finally the whole subexpression may be omitted for scripts
|
||||
# which do not pass on their parameters (i.e. after re-execing
|
||||
# they take their parameters (and potentially data) from stdin
|
||||
.?(\$\{1:?\+.?)?(\$(\@|\*))?~x
|
||||
) {
|
||||
$ret = $. - 1;
|
||||
last;
|
||||
} elsif (/^\s*(\w+)=\$0;/) {
|
||||
$var = $1;
|
||||
} elsif (
|
||||
m~
|
||||
# Match scripts which use "foo $0 $@ &\nexec true\n"
|
||||
# Program name
|
||||
\S+\s+
|
||||
|
||||
# As above
|
||||
.?\$$var.?\s*
|
||||
(--\s*)?
|
||||
.?(\$\{1:?\+.?)?(\$(\@|\*))?.?\s*\&~x
|
||||
) {
|
||||
|
||||
$backgrounded = 1;
|
||||
} elsif (
|
||||
$backgrounded
|
||||
and m~
|
||||
# the exec should either be "eval"ed or a new statement
|
||||
(^\s*|\beval\s*[\'\"]|(;|&&|\b(then|else))\s*)
|
||||
exec\s+true(\s|\Z)~x
|
||||
) {
|
||||
|
||||
$ret = $. - 1;
|
||||
last;
|
||||
} elsif (m~\@DPATCH\@~) {
|
||||
$ret = $. - 1;
|
||||
last;
|
||||
}
|
||||
|
||||
}
|
||||
close IN;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub init_hashes {
|
||||
|
||||
%bashisms = (
|
||||
qr'(?:^|\s+)function [^<>\(\)\[\]\{\};|\s]+(\s|\(|\Z)' =>
|
||||
q<'function' is useless>,
|
||||
$LEADIN . qr'select\s+\w+' => q<'select' is not POSIX>,
|
||||
qr'(test|-o|-a)\s*[^\s]+\s+==\s' => q<should be 'b = a'>,
|
||||
qr'\[\s+[^\]]+\s+==\s' => q<should be 'b = a'>,
|
||||
qr'\s\|\&' => q<pipelining is not POSIX>,
|
||||
qr'[^\\\$]\{([^\s\\\}]*?,)+[^\\\}\s]*\}' => q<brace expansion>,
|
||||
qr'\{\d+\.\.\d+(?:\.\.\d+)?\}' =>
|
||||
q<brace expansion, {a..b[..c]}should be $(seq a [c] b)>,
|
||||
qr'(?i)\{[a-z]\.\.[a-z](?:\.\.\d+)?\}' => q<brace expansion>,
|
||||
qr'(?:^|\s+)\w+\[\d+\]=' => q<bash arrays, H[0]>,
|
||||
$LEADIN
|
||||
. qr'read\s+(?:-[a-qs-zA-Z\d-]+)' =>
|
||||
q<read with option other than -r>,
|
||||
$LEADIN
|
||||
. qr'read\s*(?:-\w+\s*)*(?:\".*?\"|[\'].*?[\'])?\s*(?:;|$)' =>
|
||||
q<read without variable>,
|
||||
$LEADIN . qr'echo\s+(-n\s+)?-n?en?\s' => q<echo -e>,
|
||||
$LEADIN . qr'exec\s+-[acl]' => q<exec -c/-l/-a name>,
|
||||
$LEADIN . qr'let\s' => q<let ...>,
|
||||
qr'(?<![\$\(])\(\(.*\)\)' => q<'((' should be '$(('>,
|
||||
qr'(?:^|\s+)(\[|test)\s+-a' => q<test with unary -a (should be -e)>,
|
||||
qr'\&>' => q<should be \>word 2\>&1>,
|
||||
qr'(<\&|>\&)\s*((-|\d+)[^\s;|)}`&\\\\]|[^-\d\s]+(?<!\$)(?!\d))' =>
|
||||
q<should be \>word 2\>&1>,
|
||||
qr'\[\[(?!:)' =>
|
||||
q<alternative test command ([[ foo ]] should be [ foo ])>,
|
||||
qr'/dev/(tcp|udp)' => q</dev/(tcp|udp)>,
|
||||
$LEADIN . qr'builtin\s' => q<builtin>,
|
||||
$LEADIN . qr'caller\s' => q<caller>,
|
||||
$LEADIN . qr'compgen\s' => q<compgen>,
|
||||
$LEADIN . qr'complete\s' => q<complete>,
|
||||
$LEADIN . qr'declare\s' => q<declare>,
|
||||
$LEADIN . qr'dirs(\s|\Z)' => q<dirs>,
|
||||
$LEADIN . qr'disown\s' => q<disown>,
|
||||
$LEADIN . qr'enable\s' => q<enable>,
|
||||
$LEADIN . qr'mapfile\s' => q<mapfile>,
|
||||
$LEADIN . qr'readarray\s' => q<readarray>,
|
||||
$LEADIN . qr'shopt(\s|\Z)' => q<shopt>,
|
||||
$LEADIN . qr'suspend\s' => q<suspend>,
|
||||
$LEADIN . qr'time\s' => q<time>,
|
||||
$LEADIN . qr'type\s' => q<type>,
|
||||
$LEADIN . qr'typeset\s' => q<typeset>,
|
||||
$LEADIN . qr'ulimit(\s|\Z)' => q<ulimit>,
|
||||
$LEADIN . qr'set\s+-[BHT]+' => q<set -[BHT]>,
|
||||
$LEADIN . qr'alias\s+-p' => q<alias -p>,
|
||||
$LEADIN . qr'unalias\s+-a' => q<unalias -a>,
|
||||
$LEADIN . qr'local\s+-[a-zA-Z]+' => q<local -opt>,
|
||||
# function '=' is special-cased due to bash arrays (think of "foo=()")
|
||||
qr'(?:^|\s)\s*=\s*\(\s*\)\s*([\{|\(]|\Z)' =>
|
||||
q<function names should only contain [a-z0-9_]>,
|
||||
qr'(?:^|\s)(?<func>function\s)?\s*(?:[^<>\(\)\[\]\{\};|\s]*[^<>\(\)\[\]\{\};|\s\w][^<>\(\)\[\]\{\};|\s]*)(?(<func>)(?=)|(?<!=))\s*(?(<func>)(?:\(\s*\))?|\(\s*\))\s*([\{|\(]|\Z)'
|
||||
=> q<function names should only contain [a-z0-9_]>,
|
||||
$LEADIN . qr'(push|pop)d(\s|\Z)' => q<(push|pop)d>,
|
||||
$LEADIN . qr'export\s+-[^p]' => q<export only takes -p as an option>,
|
||||
qr'(?:^|\s+)[<>]\(.*?\)' => q<\<() process substitution>,
|
||||
$LEADIN . qr'readonly\s+-[af]' => q<readonly -[af]>,
|
||||
$LEADIN . qr'(sh|\$\{?SHELL\}?) -[rD]' => q<sh -[rD]>,
|
||||
$LEADIN . qr'(sh|\$\{?SHELL\}?) --\w+' => q<sh --long-option>,
|
||||
$LEADIN . qr'(sh|\$\{?SHELL\}?) [-+]O' => q<sh [-+]O>,
|
||||
qr'\[\^[^]]+\]' => q<[^] should be [!]>,
|
||||
$LEADIN
|
||||
. qr'printf\s+-v' =>
|
||||
q<'printf -v var ...' should be var='$(printf ...)'>,
|
||||
$LEADIN . qr'coproc\s' => q<coproc>,
|
||||
qr';;?&' => q<;;& and ;& special case operators>,
|
||||
$LEADIN . qr'jobs\s' => q<jobs>,
|
||||
# $LEADIN . qr'jobs\s+-[^lp]\s' => q<'jobs' with option other than -l or -p>,
|
||||
$LEADIN
|
||||
. qr'command\s+(?:-[pvV]+\s+)*-(?:[pvV])*[^pvV\s]' =>
|
||||
q<'command' with option other than -p, -v or -V>,
|
||||
$LEADIN
|
||||
. qr'setvar\s' =>
|
||||
q<setvar 'foo' 'bar' should be eval 'foo="'"$bar"'"'>,
|
||||
$LEADIN
|
||||
. qr'trap\s+["\']?.*["\']?\s+.*(?:ERR|DEBUG|RETURN)' =>
|
||||
q<trap with ERR|DEBUG|RETURN>,
|
||||
$LEADIN
|
||||
. qr'(?:exit|return)\s+-\d' =>
|
||||
q<exit|return with negative status code>,
|
||||
$LEADIN
|
||||
. qr'(?:exit|return)\s+--' =>
|
||||
q<'exit --' should be 'exit' (idem for return)>,
|
||||
$LEADIN . qr'hash(\s|\Z)' => q<hash>,
|
||||
qr'(?:[:=\s])~(?:[+-]|[+-]?\d+)(?:[/\s]|\Z)' =>
|
||||
q<non-standard tilde expansion>,
|
||||
);
|
||||
|
||||
%string_bashisms = (
|
||||
qr'\$\[[^][]+\]' => q<'$[' should be '$(('>,
|
||||
qr'\$\{(?:\w+|@|\*)\:(?:\d+|\$\{?\w+\}?)+(?::(?:\d+|\$\{?\w+\}?)+)?\}'
|
||||
=> q<${foo:3[:1]}>,
|
||||
qr'\$\{!\w+[\@*]\}' => q<${!prefix[*|@]>,
|
||||
qr'\$\{!\w+\}' => q<${!name}>,
|
||||
qr'\$\{(?:\w+|@|\*)([,^]{1,2}.*?)\}' =>
|
||||
q<${parm,[,][pat]} or ${parm^[^][pat]}>,
|
||||
qr'\$\{[@*]([#%]{1,2}.*?)\}' => q<${[@|*]#[#]pat} or ${[@|*]%[%]pat}>,
|
||||
qr'\$\{#[@*]\}' => q<${#@} or ${#*}>,
|
||||
qr'\$\{(?:\w+|@|\*)(/.+?){1,2}\}' => q<${parm/?/pat[/str]}>,
|
||||
qr'\$\{\#?\w+\[.+\](?:[/,:#%^].+?)?\}' =>
|
||||
q<bash arrays, ${name[0|*|@]}>,
|
||||
qr'\$\{?RANDOM\}?\b' => q<$RANDOM>,
|
||||
qr'\$\{?(OS|MACH)TYPE\}?\b' => q<$(OS|MACH)TYPE>,
|
||||
qr'\$\{?HOST(TYPE|NAME)\}?\b' => q<$HOST(TYPE|NAME)>,
|
||||
qr'\$\{?DIRSTACK\}?\b' => q<$DIRSTACK>,
|
||||
qr'\$\{?EUID\}?\b' => q<$EUID should be "$(id -u)">,
|
||||
qr'\$\{?UID\}?\b' => q<$UID should be "$(id -ru)">,
|
||||
qr'\$\{?SECONDS\}?\b' => q<$SECONDS>,
|
||||
qr'\$\{?BASH_[A-Z]+\}?\b' => q<$BASH_SOMETHING>,
|
||||
qr'\$\{?SHELLOPTS\}?\b' => q<$SHELLOPTS>,
|
||||
qr'\$\{?PIPESTATUS\}?\b' => q<$PIPESTATUS>,
|
||||
qr'\$\{?SHLVL\}?\b' => q<$SHLVL>,
|
||||
qr'\$\{?FUNCNAME\}?\b' => q<$FUNCNAME>,
|
||||
qr'\$\{?TMOUT\}?\b' => q<$TMOUT>,
|
||||
qr'(?:^|\s+)TMOUT=' => q<TMOUT=>,
|
||||
qr'\$\{?TIMEFORMAT\}?\b' => q<$TIMEFORMAT>,
|
||||
qr'(?:^|\s+)TIMEFORMAT=' => q<TIMEFORMAT=>,
|
||||
qr'(?<![$\\])\$\{?_\}?\b' => q<$_>,
|
||||
qr'(?:^|\s+)GLOBIGNORE=' => q<GLOBIGNORE=>,
|
||||
qr'<<<' => q<\<\<\< here string>,
|
||||
$LEADIN
|
||||
. qr'echo\s+(?:-[^e\s]+\s+)?\"[^\"]*(\\[abcEfnrtv0])+.*?[\"]' =>
|
||||
q<unsafe echo with backslash>,
|
||||
qr'\$\(\([\s\w$*/+-]*\w\+\+.*?\)\)' =>
|
||||
q<'$((n++))' should be '$n; $((n=n+1))'>,
|
||||
qr'\$\(\([\s\w$*/+-]*\+\+\w.*?\)\)' =>
|
||||
q<'$((++n))' should be '$((n=n+1))'>,
|
||||
qr'\$\(\([\s\w$*/+-]*\w\-\-.*?\)\)' =>
|
||||
q<'$((n--))' should be '$n; $((n=n-1))'>,
|
||||
qr'\$\(\([\s\w$*/+-]*\-\-\w.*?\)\)' =>
|
||||
q<'$((--n))' should be '$((n=n-1))'>,
|
||||
qr'\$\(\([\s\w$*/+-]*\*\*.*?\)\)' => q<exponentiation is not POSIX>,
|
||||
$LEADIN . qr'printf\s["\'][^"\']*?%q.+?["\']' => q<printf %q>,
|
||||
);
|
||||
|
||||
%singlequote_bashisms = (
|
||||
$LEADIN
|
||||
. qr'echo\s+(?:-[^e\s]+\s+)?\'[^\']*(\\[abcEfnrtv0])+.*?[\']' =>
|
||||
q<unsafe echo with backslash>,
|
||||
$LEADIN
|
||||
. qr'source\s+[\"\']?(?:\.\/|\/|\$|[\w~.-])\S*' =>
|
||||
q<should be '.', not 'source'>,
|
||||
);
|
||||
|
||||
if ($opt_echo) {
|
||||
$bashisms{ $LEADIN . qr'echo\s+-[A-Za-z]*n' } = q<echo -n>;
|
||||
}
|
||||
if ($opt_posix) {
|
||||
$bashisms{ $LEADIN . qr'local\s+\w+(\s+\W|\s*[;&|)]|$)' }
|
||||
= q<local foo>;
|
||||
$bashisms{ $LEADIN . qr'local\s+\w+=' } = q<local foo=bar>;
|
||||
$bashisms{ $LEADIN . qr'local\s+\w+\s+\w+' } = q<local x y>;
|
||||
$bashisms{ $LEADIN . qr'((?:test|\[)\s+.+\s-[ao])\s' } = q<test -a/-o>;
|
||||
$bashisms{ $LEADIN . qr'kill\s+-[^sl]\w*' } = q<kill -[0-9] or -[A-Z]>;
|
||||
$bashisms{ $LEADIN . qr'trap\s+["\']?.*["\']?\s+.*[1-9]' }
|
||||
= q<trap with signal numbers>;
|
||||
}
|
||||
|
||||
if ($makefile) {
|
||||
$string_bashisms{qr'(\$\(|\`)\s*\<\s*([^\s\)]{2,}|[^DF])\s*(\)|\`)'}
|
||||
= q<'$(\< foo)' should be '$(cat foo)'>;
|
||||
} else {
|
||||
$bashisms{ $LEADIN . qr'\w+\+=' } = q<should be VAR="${VAR}foo">;
|
||||
$string_bashisms{qr'(\$\(|\`)\s*\<\s*\S+\s*(\)|\`)'}
|
||||
= q<'$(\< foo)' should be '$(cat foo)'>;
|
||||
}
|
||||
|
||||
if ($opt_extra) {
|
||||
$string_bashisms{qr'\$\{?BASH\}?\b'} = q<$BASH>;
|
||||
$string_bashisms{qr'(?:^|\s+)RANDOM='} = q<RANDOM=>;
|
||||
$string_bashisms{qr'(?:^|\s+)(OS|MACH)TYPE='} = q<(OS|MACH)TYPE=>;
|
||||
$string_bashisms{qr'(?:^|\s+)HOST(TYPE|NAME)='} = q<HOST(TYPE|NAME)=>;
|
||||
$string_bashisms{qr'(?:^|\s+)DIRSTACK='} = q<DIRSTACK=>;
|
||||
$string_bashisms{qr'(?:^|\s+)EUID='} = q<EUID=>;
|
||||
$string_bashisms{qr'(?:^|\s+)UID='} = q<UID=>;
|
||||
$string_bashisms{qr'(?:^|\s+)BASH(_[A-Z]+)?='} = q<BASH(_SOMETHING)=>;
|
||||
$string_bashisms{qr'(?:^|\s+)SHELLOPTS='} = q<SHELLOPTS=>;
|
||||
$string_bashisms{qr'\$\{?POSIXLY_CORRECT\}?\b'} = q<$POSIXLY_CORRECT>;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
#!/bin/sh
|
||||
vol_on=$(amixer get Master | tail -n 1 | cut -d ' ' -f 8)
|
||||
vol=$(amixer get Master | awk -F'[][]' 'END{ print $2 }')
|
||||
if [ $vol_on = '[on]' ]; then
|
||||
echo "" $vol;
|
||||
if [ "$vol_on" = '[on]' ]; then
|
||||
echo " $vol";
|
||||
else
|
||||
printf " \n";
|
||||
fi;
|
||||
|
|
16
varios/hosts
16
varios/hosts
|
@ -9,31 +9,31 @@
|
|||
|
||||
# Realizar copia de seguridad del fichero hosts en caso de no existir
|
||||
if [ ! -f /etc/hosts.bak ]; then
|
||||
printf '%b' "\033[32;1mCreando copia de seguridad del fichero hosts...\033[0m\n";
|
||||
doas cp /etc/hosts /etc/hosts.bak && sleep 1s; printf '%b' "\033[33;1mCopia finalizada\033[0m\n"
|
||||
printf "\033[32;1mCreando copia de seguridad del fichero hosts...\033[0m\n";
|
||||
doas cp /etc/hosts /etc/hosts.bak && sleep 1s; printf "\033[33;1mCopia finalizada\033[0m\n"
|
||||
else
|
||||
printf '%b' "\033[35;5mYa existe copia de seguridad del fichero hosts\033[0m\n"
|
||||
printf "\033[35;5mYa existe copia de seguridad del fichero hosts\033[0m\n"
|
||||
fi
|
||||
|
||||
# Descargar actualizaciones mas reciente del repositorio y copiarlo al fichero hosts
|
||||
if [ ! -w /etc/hosts ]; then
|
||||
doas chmod o+w /etc/hosts && sleep 1s;
|
||||
printf '%b' "\033[32;1mDescargando y copiando lista actualizada para fichero hosts...\033[0m\n" &&
|
||||
printf "\033[32;1mDescargando y copiando lista actualizada para fichero hosts...\033[0m\n" &&
|
||||
wget -O /etc/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn/hosts && sleep 1s;
|
||||
else
|
||||
printf '%b' "\033[32;1mDescargando y copiando lista actualizada para fichero hosts...\033[0m\n" &&
|
||||
printf "\033[32;1mDescargando y copiando lista actualizada para fichero hosts...\033[0m\n" &&
|
||||
wget -O /etc/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn/hosts && sleep 1s;
|
||||
fi
|
||||
|
||||
# Agregar lista personalizada de páginas al fichero hosts
|
||||
#printf '%b' "\033[32;1mAgregando parche de la lista personalizada al fichero hosts...\033[0m\n";
|
||||
#printf "\033[32;1mAgregando parche de la lista personalizada al fichero hosts...\033[0m\n";
|
||||
#cat /home/skynet/Datos/Git/archivos_diversos/parche >> /etc/hosts; sleep 2;
|
||||
#printf '%b' "\033[33;1mParche aplicado\033[0m\n";
|
||||
#printf "\033[33;1mParche aplicado\033[0m\n";
|
||||
|
||||
~/.local/bin/dunst_sound &
|
||||
|
||||
# Notificacion de actualizacion del fichero
|
||||
printf '%b' "\033[36;1mFichero hosts actualizado.\nTarea finalizada.\033[0m\n";
|
||||
printf "\033[36;1mFichero hosts actualizado.\nTarea finalizada.\033[0m\n";
|
||||
#notify-send -t 5000 -i /home/skynet/.icons/status/hosts_update.png "Tarea finalizada" 'Fichero hosts actualizado'
|
||||
#printf 'IMG:/home/skynet/Datos/Git_Hub/Void_Linux/otros/icons/status/hosts_update.png\tTarea finalizada\tFichero hosts actualizado\n' > $XNOTIFY_FIFO
|
||||
herbe "Lista de fichero hosts actualizado"
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
.TH CHECKBASHISMS 1 "Debian Utilities" "DEBIAN" \" -*- nroff -*-
|
||||
.SH NAME
|
||||
checkbashisms \- check for bashisms in /bin/sh scripts
|
||||
.SH SYNOPSIS
|
||||
\fBcheckbashisms\fR \fIscript\fR ...
|
||||
.br
|
||||
\fBcheckbashisms \-\-help\fR|\fB\-\-version\fR
|
||||
.SH DESCRIPTION
|
||||
\fBcheckbashisms\fR, based on one of the checks from the \fBlintian\fR
|
||||
system, performs basic checks on \fI/bin/sh\fR shell scripts for the
|
||||
possible presence of bashisms. It takes the names of the shell
|
||||
scripts on the command line, and outputs warnings if possible bashisms
|
||||
are detected.
|
||||
.PP
|
||||
Note that the definition of a bashism in this context roughly equates
|
||||
to "a shell feature that is not required to be supported by POSIX"; this
|
||||
means that some issues flagged may be permitted under optional sections
|
||||
of POSIX, such as XSI or User Portability.
|
||||
.PP
|
||||
In cases where POSIX and Debian Policy disagree, \fBcheckbashisms\fR by
|
||||
default allows extensions permitted by Policy but may also provide
|
||||
options for stricter checking.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-\-help ", " \-h
|
||||
Show a summary of options.
|
||||
.TP
|
||||
.BR \-\-newline ", " \-n
|
||||
Check for "\fBecho \-n\fR" usage (non POSIX but required by Debian Policy 10.4.)
|
||||
.TP
|
||||
.BR \-\-posix ", " \-p
|
||||
Check for issues which are non POSIX but required to be supported by Debian
|
||||
Policy 10.4 (implies \fB\-n\fR).
|
||||
.TP
|
||||
.BR \-\-force ", " \-f
|
||||
Force each script to be checked, even if it would normally not be (for
|
||||
instance, it has a bash or non POSIX shell shebang or appears to be a
|
||||
shell wrapper).
|
||||
.TP
|
||||
.BR \-\-extra ", " \-x
|
||||
Highlight lines which, whilst they do not contain bashisms, may be
|
||||
useful in determining whether a particular issue is a false positive
|
||||
which may be ignored.
|
||||
For example, the use of "\fB$BASH_ENV\fR" may be preceded by checking
|
||||
whether "\fB$BASH\fR" is set.
|
||||
.TP
|
||||
.BR \-\-early-fail ", " \-e
|
||||
Exit right after a first error is seen.
|
||||
.TP
|
||||
.BR \-\-version ", " \-v
|
||||
Show version and copyright information.
|
||||
.SH "EXIT VALUES"
|
||||
The exit value will be 0 if no possible bashisms or other problems
|
||||
were detected. Otherwise it will be the sum of the following error
|
||||
values:
|
||||
.TP
|
||||
1
|
||||
A possible bashism was detected.
|
||||
.TP
|
||||
2
|
||||
A file was skipped for some reason, for example, because it was
|
||||
unreadable or not found. The warning message will give details.
|
||||
.TP
|
||||
4
|
||||
No bashisms were detected in a bash script.
|
||||
.SH "SEE ALSO"
|
||||
.BR lintian (1)
|
||||
.SH AUTHOR
|
||||
\fBcheckbashisms\fR was originally written as a shell script by Yann Dirson
|
||||
<\fIdirson@debian.org\fR> and rewritten in Perl with many more features by
|
||||
Julian Gilbey <\fIjdg@debian.org\fR>.
|
|
@ -1,23 +1,27 @@
|
|||
#!/bin/sh
|
||||
|
||||
RET=$(echo "" Apagar"\n" Reiniciar"\n" Bloquear"\n" Suspender"\n" Hibernar"\n" logout"\nCancelar" | dmenu -l 7 -p " Menu")
|
||||
RET=$(printf " Apagar\n Reiniciar\n Bloquear\n Suspender\n Hibernar\n logout\nCancelar" | dmenu -l 7 -p " Menu")
|
||||
|
||||
#RET=$(echo "" Apagar"\n" Reiniciar"\n" Bloquear"\n" Suspender"\n" logout"\ncancel" | dmenu -l 7 -p " Logout")
|
||||
case $RET in
|
||||
" Apagar")
|
||||
st -T "warning" -g "42x8+480+300" -f "Liberation Mono:size=12" -e su - root -c 'shutdown -h now'
|
||||
#st -T "warning" -g "42x8+480+300" -f "Liberation Mono:size=12" -e su - root -c 'shutdown -h now'
|
||||
urxvtc -T 'warning' -geometry '42x8-540-320' -imfont 'liberationmono:bold:pixelsize=12' -e su - root -c 'shutdown -h now'
|
||||
;;
|
||||
" Reiniciar")
|
||||
st -T "warning" -g "42x8+480+300" -f "Liberation Mono:size=12" -e su - root -c 'shutdown -r now'
|
||||
#st -T "warning" -g "42x8+480+300" -f "Liberation Mono:size=12" -e su - root -c 'shutdown -r now'
|
||||
urxvtc -T 'warning' -geometry '42x8-540-320' -imfont 'liberationmono:bold:pixelsize=12' -e su - root -c 'shutdown -r now'
|
||||
;;
|
||||
" Bloquear")
|
||||
slock
|
||||
;;
|
||||
" Suspender")
|
||||
st -T 'warning' -g '42x8+480+300' -f 'Liberation Mono:size=12' -e su - root -c zzz && slock
|
||||
#st -T 'warning' -g '42x8+480+300' -f 'Liberation Mono:size=12' -e su - root -c zzz && slock
|
||||
urxvtc -T 'warning' -geometry '42x8-540-320' -imfont 'liberationmono:bold:pixelsize=12' -e su - root -c 'zzz && slock'
|
||||
;;
|
||||
" Hibernar")
|
||||
st -T "warning" -g "42x8+480+300" -f "Liberation Mono:size=12" -e su - root -c ZZZ && slock
|
||||
#st -T "warning" -g "42x8+480+300" -f "Liberation Mono:size=12" -e su - root -c ZZZ && slock
|
||||
urxvtc -T 'warning' -geometry '42x8-540-320' -imfont 'liberationmono:bold:pixelsize=12' -e su - root -c 'ZZZ && slock'
|
||||
;;
|
||||
" logout")
|
||||
pkill startdwm && xdotool key "super+shift+q"
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#!/bin/sh
|
||||
## NOTA: este script aún está en fase de pruebas
|
||||
## Convertir audio ogg a aac
|
||||
#ffmpeg -i input.ogg -strict experimental -acodec aac output.aac
|
||||
## Añadir audio a video
|
||||
#ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a copy videoconaudio.mp4
|
||||
## Cortar video
|
||||
## Con -ss 00:01:30.0 le estoy diciendo que tome el video a partir del minuto 1:30 y
|
||||
## luego con -t 00:00:10.0 le digo que tome los 10 segundos que siguen, es decir me
|
||||
## creara un video de 10 segundos
|
||||
#ffmpeg -i input.mp4 -ss 00:01:30 -t 00:00:10 -c copy output.mp4
|
||||
## Para quitar audio a un video hacerlo del siguiente modo:
|
||||
#ffmpeg -i $input_file -c copy -an $output_file
|
||||
|
||||
|
||||
cd "$HOME" || exit
|
||||
audio(){
|
||||
if [ -f "$(find ./* -prune -name "audio*.ogg")" ]; then
|
||||
mv audio*.ogg input.ogg
|
||||
ffmpeg -i input.ogg -strict experimental -acodec aac audio.aac
|
||||
fi
|
||||
}
|
||||
|
||||
video(){
|
||||
if [ -f "$(find ./* -prune -name "video*.mp4")" ]; then
|
||||
mv video*.mp4 input.mp4
|
||||
ffmpeg -i input.mp4 -i audio.aac -c:v copy -c:a copy final.mp4
|
||||
fi
|
||||
}
|
||||
|
||||
convert(){
|
||||
audio && video
|
||||
if [ -f "$HOME/final.mp4" ]; then
|
||||
mv input.* audio.aac "$HOME/.local/share/Trash/files"
|
||||
fi
|
||||
}
|
||||
|
||||
convert && exit
|
|
@ -13,7 +13,7 @@ fi
|
|||
|
||||
# Obtener netbsd-curses y compilar bibliotecas estáticas
|
||||
[ ! -d "./netbsd-curses" ] && git clone https://github.com/sabotage-linux/netbsd-curses
|
||||
cd netbsd-curses
|
||||
cd netbsd-curses || exit
|
||||
git checkout v0.3.2
|
||||
make CC=gcc CFLAGS="-O3 -fPIC" LDFLAGS=-static all-static -j$(($(nproc)+1))
|
||||
doas busybox.static cp libcurses/libcurses.a libterminfo/libterminfo.a /opt/nnn-libs/
|
||||
|
@ -21,7 +21,7 @@ cd ..
|
|||
|
||||
# Compilar la biblioteca estática de musl-fts
|
||||
[ ! -d "./musl-fts" ] && git clone https://github.com/void-linux/musl-fts --depth=1
|
||||
cd musl-fts
|
||||
cd musl-fts || exit
|
||||
./bootstrap.sh
|
||||
./configure
|
||||
make CC=gcc CFLAGS=-O3 LDFLAGS=-static -j$(($(nproc)+1))
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Para poder utilizar estos plugins se recomienda copiarlos al siguiente directorio:
|
||||
/usr/lib/urxvt/perl/
|
|
@ -0,0 +1,486 @@
|
|||
#!/usr/bin/env perl
|
||||
#
|
||||
# On-the-fly adjusting of the font size in urxvt
|
||||
#
|
||||
# Copyright (c) 2008 David O'Neill
|
||||
# 2012 Noah K. Tilton <noahktilton@gmail.com>
|
||||
# 2009-2012 Simon Lundström <simmel@soy.se>
|
||||
# 2012-2016 Jan Larres <jan@majutsushi.net>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
#
|
||||
# URL: https://github.com/majutsushi/urxvt-font-size
|
||||
#
|
||||
# Based on:
|
||||
# https://github.com/dave0/urxvt-font-size
|
||||
# https://github.com/noah/urxvt-font
|
||||
# https://github.com/simmel/urxvt-resize-font
|
||||
#
|
||||
# X11 fonts background:
|
||||
# http://keithp.com/~keithp/talks/xtc2001/paper/
|
||||
|
||||
#:META:X_RESOURCE:%.step:interger:font size increase/decrease step
|
||||
|
||||
=head1 NAME
|
||||
|
||||
font-size - interactive font size setter
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
Put the font-size script into $HOME/.urxvt/ext/ and add it to the list
|
||||
of enabled perl-extensions in ~/.Xresources:
|
||||
|
||||
URxvt.perl-ext-common: ...,font-size
|
||||
|
||||
The extension automatically binds Ctrl++ to the 'increase' function,
|
||||
Ctrl+- to 'decrease', and Ctrl+0 to 'reset'. To use the other available functions
|
||||
or change the keys, add some keybindings of your own:
|
||||
|
||||
URxvt.keysym.C-Up: font-size:increase
|
||||
URxvt.keysym.C-Down: font-size:decrease
|
||||
URxvt.keysym.C-S-Up: font-size:incglobal
|
||||
URxvt.keysym.C-S-Down: font-size:decglobal
|
||||
URxvt.keysym.C-equal: font-size:reset
|
||||
URxvt.keysym.C-slash: font-size:show
|
||||
|
||||
Note that for urxvt versions older than 9.21 the resources have to look like this:
|
||||
|
||||
URxvt.keysym.C-Up: perl:font-size:increase
|
||||
URxvt.keysym.C-Down: perl:font-size:decrease
|
||||
URxvt.keysym.C-S-Up: perl:font-size:incglobal
|
||||
URxvt.keysym.C-S-Down: perl:font-size:decglobal
|
||||
URxvt.keysym.C-equal: perl:font-size:reset
|
||||
URxvt.keysym.C-slash: perl:font-size:show
|
||||
|
||||
Supported functions:
|
||||
|
||||
=over 2
|
||||
|
||||
=item * increase/decrease:
|
||||
|
||||
increase or decrease the font size of the current terminal.
|
||||
|
||||
=item * incglobal/decglobal:
|
||||
|
||||
same as above and also adjust the X server values so all newly
|
||||
started terminals will use the same fontsize.
|
||||
|
||||
=item * incsave/decsave:
|
||||
|
||||
same as incglobal/decglobal and also modify the ~/.Xresources
|
||||
file so the changed font sizes will persist over a restart of
|
||||
the X server or a reboot.
|
||||
|
||||
=item * reset:
|
||||
|
||||
reset the font size to the value of the resource when starting
|
||||
the terminal.
|
||||
|
||||
=item * show
|
||||
|
||||
show the current value of the 'font' resource in a popup.
|
||||
|
||||
=back
|
||||
|
||||
You can also change the step size that the script will use to increase
|
||||
the font size:
|
||||
|
||||
URxvt.font-size.step: 4
|
||||
|
||||
The default step size is 1. This means that with this setting a
|
||||
size change sequence would be for example 8->12->16->20 instead of
|
||||
8->9->10->11->12 etc. Please note that many X11 fonts are only
|
||||
available in specific sizes, though, and odd sizes are often not
|
||||
available, resulting in an effective step size of 2 instead of 1
|
||||
in that case.
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my %escapecodes = (
|
||||
"font" => 710,
|
||||
"boldFont" => 711,
|
||||
"italicFont" => 712,
|
||||
"boldItalicFont" => 713
|
||||
);
|
||||
|
||||
sub on_init {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->bind_action ("C-plus", "%:increase")
|
||||
or warn "unable to register 'C-plus' as font-size increase hotkey\n";
|
||||
$self->bind_action ("C-minus", "%:decrease")
|
||||
or warn "unable to register 'C-minus' as font-size decrease hotkey\n";
|
||||
$self->bind_action ("C-0", "%:reset")
|
||||
or warn "unable to register 'C-0' as font-size reset hotkey\n";
|
||||
}
|
||||
|
||||
sub on_start
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
$self->{step} = $self->x_resource("%.step") || 1;
|
||||
|
||||
foreach my $type (qw(font boldFont italicFont boldItalicFont)) {
|
||||
$self->{$type} = $self->x_resource($type) || "undef";
|
||||
}
|
||||
}
|
||||
|
||||
# Needed for backwards compatibility with < 9.21
|
||||
sub on_user_command
|
||||
{
|
||||
my ($self, $cmd) = @_;
|
||||
|
||||
my $step = $self->{step};
|
||||
|
||||
if ($cmd eq "font-size:increase") {
|
||||
fonts_change_size($self, $step, 0);
|
||||
} elsif ($cmd eq "font-size:decrease") {
|
||||
fonts_change_size($self, -$step, 0);
|
||||
} elsif ($cmd eq "font-size:incglobal") {
|
||||
fonts_change_size($self, $step, 1);
|
||||
} elsif ($cmd eq "font-size:decglobal") {
|
||||
fonts_change_size($self, -$step, 1);
|
||||
} elsif ($cmd eq "font-size:incsave") {
|
||||
fonts_change_size($self, $step, 2);
|
||||
} elsif ($cmd eq "font-size:decsave") {
|
||||
fonts_change_size($self, -$step, 2);
|
||||
} elsif ($cmd eq "font-size:reset") {
|
||||
fonts_reset($self);
|
||||
} elsif ($cmd eq "font-size:show") {
|
||||
fonts_show($self);
|
||||
}
|
||||
}
|
||||
|
||||
sub on_action
|
||||
{
|
||||
my ($self, $action) = @_;
|
||||
|
||||
my $step = $self->{step};
|
||||
|
||||
if ($action eq "increase") {
|
||||
fonts_change_size($self, $step, 0);
|
||||
} elsif ($action eq "decrease") {
|
||||
fonts_change_size($self, -$step, 0);
|
||||
} elsif ($action eq "incglobal") {
|
||||
fonts_change_size($self, $step, 1);
|
||||
} elsif ($action eq "decglobal") {
|
||||
fonts_change_size($self, -$step, 1);
|
||||
} elsif ($action eq "incsave") {
|
||||
fonts_change_size($self, $step, 2);
|
||||
} elsif ($action eq "decsave") {
|
||||
fonts_change_size($self, -$step, 2);
|
||||
} elsif ($action eq "reset") {
|
||||
fonts_reset($self);
|
||||
} elsif ($action eq "show") {
|
||||
fonts_show($self);
|
||||
}
|
||||
}
|
||||
|
||||
sub fonts_change_size
|
||||
{
|
||||
my ($term, $delta, $save) = @_;
|
||||
|
||||
my @newfonts = ();
|
||||
|
||||
my $curres = $term->resource('font');
|
||||
if (!$curres) {
|
||||
$term->scr_add_lines("\r\nWarning: No font configured, trying a default.\r\nPlease set a font with the 'URxvt.font' resource.");
|
||||
$curres = "fixed";
|
||||
}
|
||||
my @curfonts = split(/\s*,\s*/, $curres);
|
||||
|
||||
my $basefont = shift(@curfonts);
|
||||
my ($newbasefont, $newbasedelta, $newbasesize) = handle_font($term, $basefont, $delta, 0, 0);
|
||||
push @newfonts, $newbasefont;
|
||||
|
||||
# Only adjust other fonts if base font changed
|
||||
if ($newbasefont ne $basefont) {
|
||||
foreach my $font (@curfonts) {
|
||||
my ($newfont, $newdelta, $newsize) = handle_font($term, $font, $delta, $newbasedelta, $newbasesize);
|
||||
push @newfonts, $newfont;
|
||||
}
|
||||
my $newres = join(",", @newfonts);
|
||||
font_apply_new($term, $newres, "font", $save);
|
||||
|
||||
handle_type($term, "boldFont", $delta, $newbasedelta, $newbasesize, $save);
|
||||
handle_type($term, "italicFont", $delta, $newbasedelta, $newbasesize, $save);
|
||||
handle_type($term, "boldItalicFont", $delta, $newbasedelta, $newbasesize, $save);
|
||||
}
|
||||
|
||||
if ($save > 1) {
|
||||
# write the new values back to the file
|
||||
my $xresources = readlink $ENV{"HOME"} . "/.Xresources";
|
||||
system("xrdb -edit " . $xresources);
|
||||
}
|
||||
}
|
||||
|
||||
sub fonts_reset
|
||||
{
|
||||
my ($term) = @_;
|
||||
|
||||
foreach my $type (qw(font boldFont italicFont boldItalicFont)) {
|
||||
my $initial = $term->{$type};
|
||||
if ($initial ne "undef") {
|
||||
font_apply_new($term, $initial, $type, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub fonts_show
|
||||
{
|
||||
my ($term) = @_;
|
||||
|
||||
my $out = $term->resource('font');
|
||||
$out =~ s/\s*,\s*/\n/g;
|
||||
|
||||
$term->{'font-size'}{'overlay'} = {
|
||||
overlay => $term->overlay_simple(0, -1, $out),
|
||||
timer => urxvt::timer->new->start(urxvt::NOW + 5)->cb(
|
||||
sub {
|
||||
delete $term->{'font-size'}{'overlay'};
|
||||
}
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
sub handle_type
|
||||
{
|
||||
my ($term, $type, $delta, $basedelta, $basesize, $save) = @_;
|
||||
|
||||
my $curres = $term->resource($type);
|
||||
if (!$curres) {
|
||||
return;
|
||||
}
|
||||
my @curfonts = split(/\s*,\s*/, $curres);
|
||||
my @newfonts = ();
|
||||
|
||||
foreach my $font (@curfonts) {
|
||||
my ($newfont, $newdelta, $newsize) = handle_font($term, $font, $delta, $basedelta, $basesize);
|
||||
push @newfonts, $newfont;
|
||||
}
|
||||
|
||||
my $newres = join(",", @newfonts);
|
||||
font_apply_new($term, $newres, $type, $save);
|
||||
}
|
||||
|
||||
sub handle_font
|
||||
{
|
||||
my ($term, $font, $delta, $basedelta, $basesize) = @_;
|
||||
|
||||
my $newfont;
|
||||
my $newdelta;
|
||||
my $newsize;
|
||||
my $prefix = 0;
|
||||
|
||||
if ($font =~ /^\s*x:/) {
|
||||
$font =~ s/^\s*x://;
|
||||
$prefix = 1;
|
||||
}
|
||||
if ($font =~ /^\s*(\[.*\])?xft:/) {
|
||||
($newfont, $newdelta, $newsize) = font_change_size_xft($term, $font, $delta, $basedelta, $basesize);
|
||||
} elsif ($font =~ /^\s*-/) {
|
||||
($newfont, $newdelta, $newsize) = font_change_size_xlfd($term, $font, $delta, $basedelta, $basesize);
|
||||
} else {
|
||||
# check whether the font is a valid alias and if yes resolve it to the
|
||||
# actual font
|
||||
my $lsfinfo = `xlsfonts -l $font 2>/dev/null`;
|
||||
|
||||
if ($lsfinfo eq "") {
|
||||
# not a valid alias, ring the bell if it is the base font and just
|
||||
# return the current font
|
||||
if ($basesize == 0) {
|
||||
$term->scr_bell;
|
||||
}
|
||||
return ($font, $basedelta, $basesize);
|
||||
}
|
||||
|
||||
my $fontinfo = (split(/\n/, $lsfinfo))[-1];
|
||||
my ($fontfull) = ($fontinfo =~ /\s+([-a-z0-9]+$)/);
|
||||
($newfont, $newdelta, $newsize) = font_change_size_xlfd($term, $fontfull, $delta, $basedelta, $basesize);
|
||||
}
|
||||
|
||||
# $term->scr_add_lines("\r\nNew font is $newfont\n");
|
||||
if ($prefix) {
|
||||
$newfont = "x:$newfont";
|
||||
}
|
||||
return ($newfont, $newdelta, $newsize);
|
||||
}
|
||||
|
||||
sub font_change_size_xft
|
||||
{
|
||||
my ($term, $fontstring, $delta, $basedelta, $basesize) = @_;
|
||||
|
||||
my @pieces = split(/:/, $fontstring);
|
||||
my @resized = ();
|
||||
my $size = 0;
|
||||
my $new_size = 0;
|
||||
|
||||
foreach my $piece (@pieces) {
|
||||
if ($piece =~ /^(?:(?:pixel)?size=|[^=-]+-)(\d+(\.\d*)?)$/) {
|
||||
$size = $1;
|
||||
|
||||
if ($basedelta != 0) {
|
||||
$new_size = $size + $basedelta;
|
||||
} else {
|
||||
$new_size = $size + $delta;
|
||||
}
|
||||
|
||||
$piece =~ s/(=|-)$size/$1$new_size/;
|
||||
}
|
||||
push @resized, $piece;
|
||||
}
|
||||
|
||||
my $resized_str = join(":", @resized);
|
||||
|
||||
# don't make fonts too small
|
||||
if ($new_size >= 6) {
|
||||
return ($resized_str, $new_size - $size, $new_size);
|
||||
} else {
|
||||
if ($basesize == 0) {
|
||||
$term->scr_bell;
|
||||
}
|
||||
return ($fontstring, 0, $size);
|
||||
}
|
||||
}
|
||||
|
||||
sub font_change_size_xlfd
|
||||
{
|
||||
my ($term, $fontstring, $delta, $basedelta, $basesize) = @_;
|
||||
|
||||
#-xos4-terminus-medium-r-normal-*-12-*-*-*-*-*-*-1
|
||||
|
||||
my @fields = qw(foundry family weight slant setwidth style pixelSize pointSize Xresolution Yresolution spacing averageWidth registry encoding);
|
||||
|
||||
my %font;
|
||||
$fontstring =~ s/^-//; # Strip leading - before split
|
||||
@font{@fields} = split(/-/, $fontstring);
|
||||
|
||||
if ($font{pixelSize} eq '*') {
|
||||
$term->scr_add_lines("\r\nWarning: Font size undefined, assuming 12.\r\nPlease set the 'URxvt.font' resource to a font with a concrete size.");
|
||||
$font{pixelSize} = '12'
|
||||
}
|
||||
if ($font{registry} eq '*') {
|
||||
$font{registry} ='iso8859';
|
||||
}
|
||||
|
||||
# Blank out the size for the pattern
|
||||
my %pattern = %font;
|
||||
$pattern{foundry} = '*';
|
||||
$pattern{setwidth} = '*';
|
||||
$pattern{pixelSize} = '*';
|
||||
$pattern{pointSize} = '*';
|
||||
# if ($basesize != 0) {
|
||||
# $pattern{Xresolution} = '*';
|
||||
# $pattern{Yresolution} = '*';
|
||||
# }
|
||||
$pattern{averageWidth} = '*';
|
||||
# make sure there are no empty fields
|
||||
foreach my $field (@fields) {
|
||||
$pattern{$field} = '*' unless defined($pattern{$field});
|
||||
}
|
||||
my $new_fontstring = '-' . join('-', @pattern{@fields});
|
||||
|
||||
my @candidates;
|
||||
# $term->scr_add_lines("\r\nPattern is $new_fontstring\n");
|
||||
open(FOO, "xlsfonts -fn '$new_fontstring' | sort -u |") or die $!;
|
||||
while (<FOO>) {
|
||||
chomp;
|
||||
s/^-//; # Strip leading '-' before split
|
||||
my @fontdata = split(/-/, $_);
|
||||
|
||||
push @candidates, [$fontdata[6], "-$_"];
|
||||
# $term->scr_add_lines("\r\npossibly $fontdata[6] $_\n");
|
||||
}
|
||||
close(FOO);
|
||||
|
||||
if (!@candidates) {
|
||||
die "No possible fonts!";
|
||||
}
|
||||
|
||||
if ($basesize != 0) {
|
||||
# sort by font size, descending
|
||||
@candidates = sort {$b->[0] <=> $a->[0]} @candidates;
|
||||
|
||||
# font is not the base font, so find the largest font that is at most
|
||||
# as large as the base font. If the largest possible font is smaller
|
||||
# than the base font bail and hope that a 0-size font can be found at
|
||||
# the end of the function
|
||||
if ($candidates[0]->[0] > $basesize) {
|
||||
foreach my $candidate (@candidates) {
|
||||
if ($candidate->[0] <= $basesize) {
|
||||
return ($candidate->[1], $candidate->[0] - $font{pixelSize}, $candidate->[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} elsif ($delta > 0) {
|
||||
# sort by font size, ascending
|
||||
@candidates = sort {$a->[0] <=> $b->[0]} @candidates;
|
||||
|
||||
foreach my $candidate (@candidates) {
|
||||
if ($candidate->[0] >= $font{pixelSize} + $delta) {
|
||||
return ($candidate->[1], $candidate->[0] - $font{pixelSize}, $candidate->[0]);
|
||||
}
|
||||
}
|
||||
} elsif ($delta < 0) {
|
||||
# sort by font size, descending
|
||||
@candidates = sort {$b->[0] <=> $a->[0]} @candidates;
|
||||
|
||||
foreach my $candidate (@candidates) {
|
||||
if ($candidate->[0] <= $font{pixelSize} + $delta && $candidate->[0] != 0) {
|
||||
return ($candidate->[1], $candidate->[0] - $font{pixelSize}, $candidate->[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# no fitting font available, check whether a 0-size font can be used to
|
||||
# fit the size of the base font
|
||||
@candidates = sort {$a->[0] <=> $b->[0]} @candidates;
|
||||
if ($basesize != 0 && $candidates[0]->[0] == 0) {
|
||||
return ($candidates[0]->[1], $basedelta, $basesize);
|
||||
} else {
|
||||
# if there is absolutely no smaller/larger font that can be used
|
||||
# return the current one, and beep if this is the base font
|
||||
if ($basesize == 0) {
|
||||
$term->scr_bell;
|
||||
}
|
||||
return ("-$fontstring", 0, $font{pixelSize});
|
||||
}
|
||||
}
|
||||
|
||||
sub font_apply_new
|
||||
{
|
||||
my ($term, $newfont, $type, $save) = @_;
|
||||
|
||||
# $term->scr_add_lines("\r\nnew font is $newfont\n");
|
||||
|
||||
$term->cmd_parse("\033]" . $escapecodes{$type} . ";" . $newfont . "\033\\");
|
||||
|
||||
# load the xrdb db
|
||||
# system("xrdb -load " . X_RESOURCES);
|
||||
|
||||
if ($save > 0) {
|
||||
# merge the new values
|
||||
open(XRDB_MERGE, "| xrdb -merge") || die "can't fork: $!";
|
||||
local $SIG{PIPE} = sub { die "xrdb pipe broken" };
|
||||
print XRDB_MERGE "URxvt." . $type . ": " . $newfont;
|
||||
close(XRDB_MERGE) || die "bad xrdb: $! $?";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,606 @@
|
|||
#! perl -w
|
||||
# Author: Bert Muennich
|
||||
# Website: http://www.github.com/muennich/urxvt-perls
|
||||
# License: GPLv2
|
||||
|
||||
# Use keyboard shortcuts to select and copy text.
|
||||
|
||||
# Usage: put the following lines in your .Xdefaults/.Xresources:
|
||||
# URxvt.perl-ext-common: ...,keyboard-select
|
||||
# URxvt.keysym.M-Escape: perl:keyboard-select:activate
|
||||
# The following line overwrites the default Meta-s binding and allows to
|
||||
# activate keyboard-select directly in backward search mode:
|
||||
# URxvt.keysym.M-s: perl:keyboard-select:search
|
||||
|
||||
# Use Meta-Escape to activate selection mode, then use the following keys:
|
||||
# h/j/k/l: Move cursor left/down/up/right (also with arrow keys)
|
||||
# g/G/0/^/$/H/M/L/f/F/;/,/w/W/b/B/e/E: More vi-like cursor movement keys
|
||||
# '/'/?: Start forward/backward search
|
||||
# n/N: Repeat last search, N: in reverse direction
|
||||
# Ctrl-f/b: Scroll down/up one screen
|
||||
# Ctrl-d/u: Scroll down/up half a screen
|
||||
# v/V/Ctrl-v: Toggle normal/linewise/blockwise selection
|
||||
# y/Return: Copy selection to primary buffer, Return: quit afterwards
|
||||
# Y: Copy selected lines to primary buffer or cursor line and quit
|
||||
# q/Escape: Quit keyboard selection mode
|
||||
|
||||
# Options:
|
||||
# URxvt.keyboard-select.clipboard: If true, copy to clipboard too
|
||||
|
||||
|
||||
use strict;
|
||||
|
||||
sub on_start{
|
||||
my ($self) = @_;
|
||||
|
||||
$self->{clipboard} = $self->x_resource_boolean('keyboard-select.clipboard');
|
||||
|
||||
$self->{patterns}{'w'} = qr/\w[^\w\s]|\W\w|\s\S/;
|
||||
$self->{patterns}{'W'} = qr/\s\S/;
|
||||
$self->{patterns}{'b'} = qr/.*(?:\w[^\w\s]|\W\w|\s\S)/;
|
||||
$self->{patterns}{'B'} = qr/.*\s\S/;
|
||||
$self->{patterns}{'e'} = qr/[^\w\s](?=\w)|\w(?=\W)|\S(?=\s|$)/;
|
||||
$self->{patterns}{'E'} = qr/\S(?=\s|$)/;
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub on_action {
|
||||
my ($self, $action) = @_;
|
||||
|
||||
on_user_command($self, "keyboard-select:" . $action);
|
||||
}
|
||||
|
||||
|
||||
sub on_user_command {
|
||||
my ($self, $cmd) = @_;
|
||||
|
||||
if (not $self->{active}) {
|
||||
if ($cmd eq 'keyboard-select:activate') {
|
||||
activate($self);
|
||||
} elsif ($cmd eq 'keyboard-select:search') {
|
||||
activate($self, 1);
|
||||
}
|
||||
}
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub key_press {
|
||||
my ($self, $event, $keysym, $char) = @_;
|
||||
my $key = chr($keysym);
|
||||
|
||||
if (lc($key) eq 'c' && $event->{state} & urxvt::ControlMask) {
|
||||
deactivate($self);
|
||||
} elsif ($self->{search}) {
|
||||
if ($keysym == 0xff1b) {
|
||||
if ($self->{search_mode}) {
|
||||
deactivate($self);
|
||||
} else {
|
||||
$self->{search} = '';
|
||||
status_area($self);
|
||||
}
|
||||
} elsif ($keysym == 0xff08) {
|
||||
$self->{search} = substr($self->{search}, 0, -1);
|
||||
if (not $self->{search} and $self->{search_mode}) {
|
||||
deactivate($self);
|
||||
} else {
|
||||
status_area($self);
|
||||
}
|
||||
} elsif ($keysym == 0xff0d ||
|
||||
(lc($key) eq 'm' && $event->{state} & urxvt::ControlMask)) {
|
||||
my $txt = substr($self->{search}, 1);
|
||||
if ($txt) {
|
||||
$self->{pattern} = ($txt =~ m/[[:upper:]]/) ? qr/\Q$txt\E/ :
|
||||
qr/\Q$txt\E/i;
|
||||
} elsif ($self->{pattern}) {
|
||||
delete $self->{pattern};
|
||||
}
|
||||
$self->{search} = '';
|
||||
$self->screen_cur($self->{srhcr}, $self->{srhcc});
|
||||
if (not find_next($self)) {
|
||||
if ($self->{search_mode}) {
|
||||
deactivate($self);
|
||||
} else {
|
||||
status_area($self);
|
||||
}
|
||||
}
|
||||
} elsif (length($char) > 0) {
|
||||
$self->{search} .= $self->locale_decode($char);
|
||||
my $txt = substr($self->{search}, 1);
|
||||
if ($txt) {
|
||||
$self->{pattern} = ($txt =~ m/[[:upper:]]/) ? qr/\Q$txt\E/ :
|
||||
qr/\Q$txt\E/i;
|
||||
} elsif ($self->{pattern}) {
|
||||
delete $self->{pattern};
|
||||
}
|
||||
$self->screen_cur($self->{srhcr}, $self->{srhcc});
|
||||
find_next($self);
|
||||
status_area($self);
|
||||
}
|
||||
} elsif ($self->{move_to}) {
|
||||
if ($keysym == 0xff1b) {
|
||||
$self->{move_to} = 0;
|
||||
status_area($self);
|
||||
} elsif (length($char) > 0) {
|
||||
$self->{move_to} = 0;
|
||||
$self->{patterns}{'f-1'} = qr/^.*\Q$key\E/;
|
||||
$self->{patterns}{'f+1'} = qr/^.+?\Q$key\E/;
|
||||
move_to($self, ';');
|
||||
status_area($self);
|
||||
}
|
||||
} elsif ($keysym == 0xff1b || lc($key) eq 'q') {
|
||||
deactivate($self);
|
||||
} elsif (lc($key) eq 'y' || $keysym == 0xff0d ||
|
||||
(lc($key) eq 'm' && $event->{state} & urxvt::ControlMask)) {
|
||||
my $quit = 0;
|
||||
if ($key eq 'Y' && $self->{select} ne 'l') {
|
||||
$quit = !$self->{select};
|
||||
toggle_select($self, 'l');
|
||||
}
|
||||
if ($self->{select}) {
|
||||
my ($br, $bc, $er, $ec) = calc_span($self);
|
||||
$ec = $self->line($er)->l if $self->{select} eq 'l';
|
||||
$self->selection_beg($br, $bc);
|
||||
$self->selection_end($er, $ec);
|
||||
$self->selection_make($event->{time}, $self->{select} eq 'b');
|
||||
if ($self->{clipboard}) {
|
||||
$self->selection($self->selection(), 1);
|
||||
$self->selection_grab($event->{time}, 1);
|
||||
}
|
||||
if (lc($key) eq 'y') {
|
||||
$self->selection_beg(1, 0);
|
||||
$self->selection_end(1, 0);
|
||||
$self->{select} = '';
|
||||
status_area($self);
|
||||
$self->want_refresh();
|
||||
} else {
|
||||
$quit = 1;
|
||||
}
|
||||
}
|
||||
if ($quit) {
|
||||
deactivate($self);
|
||||
}
|
||||
} elsif ($key eq 'V') {
|
||||
toggle_select($self, 'l');
|
||||
} elsif ($key eq 'v') {
|
||||
if ($event->{state} & urxvt::ControlMask) {
|
||||
toggle_select($self, 'b');
|
||||
} else {
|
||||
toggle_select($self, 'n');
|
||||
}
|
||||
} elsif ($key eq 'k' || $keysym == 0xff52) {
|
||||
move_cursor($self, 'k');
|
||||
} elsif ($key eq 'j' || $keysym == 0xff54) {
|
||||
move_cursor($self, 'j');
|
||||
} elsif ($key eq 'h' || $keysym == 0xff51) {
|
||||
move_cursor($self, 'h');
|
||||
} elsif ($key eq 'l' || $keysym == 0xff53) {
|
||||
move_cursor($self, 'l');
|
||||
} elsif ($keysym == 0xff57) {
|
||||
move_cursor($self, '$');
|
||||
} elsif ($keysym == 0xff50) {
|
||||
move_cursor($self, '^');
|
||||
} elsif ('gG0^$HML' =~ m/\Q$key\E/ ||
|
||||
('fbdu' =~ m/\Q$key\E/ && $event->{state} & urxvt::ControlMask)) {
|
||||
move_cursor($self, $key);
|
||||
} elsif (lc($key) eq 'f') {
|
||||
$self->{move_to} = 1;
|
||||
$self->{move_dir} = $key eq 'F' ? -1 : 1;
|
||||
status_area($self, $key);
|
||||
} elsif (';,wWbBeE' =~ m/\Q$key\E/) {
|
||||
move_to($self, $key);
|
||||
} elsif ($key eq '/' || $key eq '?') {
|
||||
$self->{search} = $key;
|
||||
$self->{search_dir} = $key eq '?' ? -1 : 1;
|
||||
($self->{srhcr}, $self->{srhcc}) = $self->screen_cur();
|
||||
status_area($self);
|
||||
} elsif (lc($key) eq 'n') {
|
||||
find_next($self, $self->{search_dir} * ($key eq 'N' ? -1 : 1));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub move_cursor {
|
||||
my ($self, $key) = @_;
|
||||
my ($cr, $cc) = $self->screen_cur();
|
||||
my $line = $self->line($cr);
|
||||
|
||||
if ($key eq 'k' && $line->beg > $self->top_row) {
|
||||
$cr = $line->beg - 1;
|
||||
} elsif ($key eq 'j' && $line->end < $self->nrow - 1) {
|
||||
$cr = $line->end + 1;
|
||||
} elsif ($key eq 'h' && $self->{offset} > 0) {
|
||||
$self->{offset} = $line->offset_of($cr, $cc) - 1;
|
||||
$self->{dollar} = 0;
|
||||
} elsif ($key eq 'l' && $self->{offset} < $line->l - 1) {
|
||||
++$self->{offset};
|
||||
} elsif ($key eq 'f' || $key eq 'd') {
|
||||
my $vs = $self->view_start() +
|
||||
($key eq 'd' ? $self->nrow / 2 : $self->nrow - 1);
|
||||
$vs = 0 if $vs > 0;
|
||||
$cr += $vs - $self->view_start($vs);
|
||||
} elsif ($key eq 'b' || $key eq 'u') {
|
||||
my $vs = $self->view_start() -
|
||||
($key eq 'u' ? $self->nrow / 2 : $self->nrow - 1);
|
||||
$vs = $self->top_row if $vs < $self->top_row;
|
||||
$cr += $vs - $self->view_start($vs);
|
||||
} elsif ($key eq 'g') {
|
||||
($cr, $self->{offset}) = ($self->top_row, 0);
|
||||
$self->{dollar} = 0;
|
||||
} elsif ($key eq 'G') {
|
||||
($cr, $self->{offset}) = ($self->nrow - 1, 0);
|
||||
$self->{dollar} = 0;
|
||||
} elsif ($key eq '0') {
|
||||
$self->{offset} = 0;
|
||||
$self->{dollar} = 0;
|
||||
} elsif ($key eq '^') {
|
||||
my $ltxt = $self->special_decode($line->t);
|
||||
while ($ltxt =~ s/^( *)\t/$1 . " " x (8 - length($1) % 8)/e) {}
|
||||
$self->{offset} = $ltxt =~ m/^ +/ ? $+[0] : 0;
|
||||
$self->{dollar} = 0;
|
||||
} elsif ($key eq '$') {
|
||||
my $co = $line->offset_of($cr, $cc);
|
||||
$self->{dollar} = $co + 1;
|
||||
$self->{offset} = $line->l - 1;
|
||||
} elsif ($key eq 'H') {
|
||||
$cr = $self->view_start();
|
||||
} elsif ($key eq 'M') {
|
||||
$cr = $self->view_start() + $self->nrow / 2;
|
||||
} elsif ($key eq 'L') {
|
||||
$cr = $self->view_start() + $self->nrow - 1;
|
||||
}
|
||||
|
||||
$line = $self->line($cr);
|
||||
$cc = $self->{dollar} || $self->{offset} >= $line->l ? $line->l - 1 :
|
||||
$self->{offset};
|
||||
$self->screen_cur($line->coord_of($cc));
|
||||
|
||||
status_area($self);
|
||||
$self->want_refresh();
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub move_to {
|
||||
my ($self, $key) = @_;
|
||||
my ($cr, $cc) = $self->screen_cur();
|
||||
my $line = $self->line($cr);
|
||||
my $offset = $self->{offset};
|
||||
my ($dir, $pattern);
|
||||
my ($wrap, $found) = (0, 0);
|
||||
|
||||
if ($key eq ';' || $key eq ',') {
|
||||
$dir = $self->{move_dir} * ($key eq ',' ? -1 : 1);
|
||||
$pattern = $self->{patterns}{sprintf('f%+d', $dir)};
|
||||
return if not $pattern;
|
||||
} else {
|
||||
if (lc($key) eq 'b') {
|
||||
$dir = -1;
|
||||
} else {
|
||||
$dir = 1;
|
||||
++$offset if lc($key) eq 'e';
|
||||
}
|
||||
$pattern = $self->{patterns}{$key};
|
||||
$wrap = 1;
|
||||
}
|
||||
|
||||
if ($dir > 0) {
|
||||
NEXTDOWN: my $text = substr($line->t, $offset);
|
||||
if ($text =~ m/$pattern/) {
|
||||
$offset += $+[0] - 1;
|
||||
$found = 1;
|
||||
} elsif ($wrap && $line->end + 1 < $self->nrow) {
|
||||
$cr = $line->end + 1;
|
||||
$line = $self->line($cr);
|
||||
$offset = 0;
|
||||
if (lc($key) eq 'e') {
|
||||
goto NEXTDOWN;
|
||||
} else {
|
||||
$found = 1;
|
||||
}
|
||||
}
|
||||
} elsif ($dir < 0) {
|
||||
NEXTUP: my $text = substr($line->t, 0, $offset);
|
||||
if ($text =~ m/$pattern/) {
|
||||
$offset += $+[0] - length($text) - 1;
|
||||
$found = 1;
|
||||
} elsif ($wrap) {
|
||||
if ($offset > 0) {
|
||||
$offset = 0;
|
||||
$found = 1;
|
||||
} elsif ($line->beg > $self->top_row) {
|
||||
$cr = $line->beg - 1;
|
||||
$line = $self->line($cr);
|
||||
$offset = $line->l;
|
||||
goto NEXTUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
$self->{dollar} = 0;
|
||||
$self->{offset} = $offset;
|
||||
$self->screen_cur($line->coord_of($offset));
|
||||
$self->want_refresh();
|
||||
}
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub find_next {
|
||||
my ($self, $dir) = @_;
|
||||
|
||||
return if not $self->{pattern};
|
||||
$dir = $self->{search_dir} if not $dir;
|
||||
|
||||
my ($cr, $cc) = $self->screen_cur();
|
||||
my $line = $self->line($cr);
|
||||
my $offset = $line->offset_of($cr, $cc);
|
||||
my $text;
|
||||
my $found = 0;
|
||||
|
||||
++$offset if $dir > 0;
|
||||
|
||||
while (not $found) {
|
||||
if ($dir > 0) {
|
||||
$text = substr($line->t, $offset);
|
||||
if ($text =~ m/$self->{pattern}/) {
|
||||
$found = 1;
|
||||
$offset += $-[0];
|
||||
} else {
|
||||
last if $line->end >= $self->nrow;
|
||||
$line = $self->line($line->end + 1);
|
||||
$offset = 0;
|
||||
}
|
||||
} else {
|
||||
$text = substr($line->t, 0, $offset);
|
||||
if ($text =~ m/$self->{pattern}/) {
|
||||
$found = 1;
|
||||
$offset = $-[0] while $text =~ m/$self->{pattern}/g;
|
||||
} else {
|
||||
last if $line->beg <= $self->top_row;
|
||||
$line = $self->line($line->beg - 1);
|
||||
$offset = $line->l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
$self->{dollar} = 0;
|
||||
$self->{offset} = $offset;
|
||||
$self->screen_cur($line->coord_of($offset));
|
||||
status_area($self);
|
||||
$self->want_refresh();
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
|
||||
sub tt_write {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub refresh {
|
||||
my ($self) = @_;
|
||||
my ($cr, $cc) = $self->screen_cur();
|
||||
|
||||
# scroll the current cursor position into visible area
|
||||
if ($cr < $self->view_start()) {
|
||||
$self->view_start($cr);
|
||||
} elsif ($cr >= $self->view_start() + $self->nrow) {
|
||||
$self->view_start($cr - $self->nrow + 1);
|
||||
}
|
||||
|
||||
if ($self->{select}) {
|
||||
my ($hl, $reverse_cursor);
|
||||
my ($br, $bc, $er, $ec) = calc_span($self);
|
||||
|
||||
if ($self->x_resource('highlightColor')) {
|
||||
$hl = urxvt::RS_Sel;
|
||||
$reverse_cursor = 0;
|
||||
} else {
|
||||
$hl = urxvt::RS_RVid;
|
||||
$reverse_cursor = $self->{select} ne 'l';
|
||||
}
|
||||
if ($self->{select} eq 'b') {
|
||||
my $co = $self->line($cr)->offset_of($cr, $cc);
|
||||
my $dollar = $self->{dollar} && $co >= $self->{dollar} - 1;
|
||||
|
||||
my $r = $br;
|
||||
while ($r <= $er) {
|
||||
my $line = $self->line($r);
|
||||
if ($bc < $line->l) {
|
||||
$ec = $line->l if $dollar;
|
||||
my ($br, $bc) = $line->coord_of($bc);
|
||||
my ($er, $ec) = $line->coord_of($ec <= $line->l ? $ec : $line->l);
|
||||
$self->scr_xor_span($br, $bc, $er, $ec, $hl);
|
||||
} elsif ($r == $cr) {
|
||||
$reverse_cursor = 0;
|
||||
}
|
||||
$r = $line->end + 1;
|
||||
}
|
||||
} else {
|
||||
$self->scr_xor_span($br, $bc, $er, $ec, $hl);
|
||||
}
|
||||
|
||||
if ($reverse_cursor) {
|
||||
# make the cursor visible again
|
||||
$self->scr_xor_span($cr, $cc, $cr, $cc + 1, $hl);
|
||||
}
|
||||
}
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub activate {
|
||||
my ($self, $search) = @_;
|
||||
|
||||
$self->{active} = 1;
|
||||
|
||||
$self->{select} = '';
|
||||
$self->{dollar} = 0;
|
||||
$self->{move_to} = 0;
|
||||
|
||||
if ($search) {
|
||||
$self->{search} = '?';
|
||||
$self->{search_dir} = -1;
|
||||
$self->{search_mode} = 1;
|
||||
} else {
|
||||
$self->{search} = '';
|
||||
$self->{search_mode} = 0;
|
||||
}
|
||||
|
||||
($self->{oldcr}, $self->{oldcc}) = $self->screen_cur();
|
||||
($self->{srhcr}, $self->{srhcc}) = $self->screen_cur();
|
||||
$self->{old_view_start} = $self->view_start();
|
||||
$self->{old_pty_ev_events} = $self->pty_ev_events(urxvt::EV_NONE);
|
||||
|
||||
my $line = $self->line($self->{oldcr});
|
||||
$self->{offset} = $line->offset_of($self->{oldcr}, $self->{oldcc});
|
||||
|
||||
$self->selection_beg(1, 0);
|
||||
$self->selection_end(1, 0);
|
||||
|
||||
$self->enable(
|
||||
key_press => \&key_press,
|
||||
refresh_begin => \&refresh,
|
||||
refresh_end => \&refresh,
|
||||
tt_write => \&tt_write,
|
||||
);
|
||||
|
||||
if ($self->{offset} >= $line->l) {
|
||||
$self->{offset} = $line->l > 0 ? $line->l - 1 : 0;
|
||||
$self->screen_cur($line->coord_of($self->{offset}));
|
||||
$self->want_refresh();
|
||||
}
|
||||
|
||||
$self->{overlay_len} = 0;
|
||||
status_area($self);
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub deactivate {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->selection_beg(1, 0);
|
||||
$self->selection_end(1, 0);
|
||||
|
||||
delete $self->{overlay} if $self->{overlay};
|
||||
|
||||
$self->disable("key_press", "refresh_begin", "refresh_end", "tt_write");
|
||||
$self->screen_cur($self->{oldcr}, $self->{oldcc});
|
||||
$self->view_start($self->{old_view_start});
|
||||
$self->pty_ev_events($self->{old_pty_ev_events});
|
||||
|
||||
$self->want_refresh();
|
||||
|
||||
$self->{active} = 0;
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub status_area {
|
||||
my ($self, $extra) = @_;
|
||||
my ($stat, $stat_len);
|
||||
|
||||
if ($self->{search}) {
|
||||
$stat_len = $self->ncol;
|
||||
$stat = $self->{search} . ' ' x ($stat_len - length($self->{search}));
|
||||
} else {
|
||||
if ($self->{select}) {
|
||||
$stat = "-V" . ($self->{select} ne 'n' ? uc($self->{select}) : "") . "- ";
|
||||
}
|
||||
|
||||
if ($self->top_row == 0) {
|
||||
$stat .= "All";
|
||||
} elsif ($self->view_start() == $self->top_row) {
|
||||
$stat .= "Top";
|
||||
} elsif ($self->view_start() == 0) {
|
||||
$stat .= "Bot";
|
||||
} else {
|
||||
$stat .= sprintf("%2d%%",
|
||||
($self->top_row - $self->view_start) * 100 / $self->top_row);
|
||||
}
|
||||
|
||||
$stat = "$extra $stat" if $extra;
|
||||
$stat_len = length($stat);
|
||||
}
|
||||
|
||||
if (!$self->{overlay} || $self->{overlay_len} != $stat_len) {
|
||||
delete $self->{overlay} if $self->{overlay};
|
||||
$self->{overlay} = $self->overlay(-1, -1, $stat_len, 1,
|
||||
urxvt::OVERLAY_RSTYLE, 0);
|
||||
$self->{overlay_len} = $stat_len;
|
||||
}
|
||||
|
||||
$self->{overlay}->set(0, 0, $self->special_encode($stat));
|
||||
$self->{overlay}->show();
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub toggle_select {
|
||||
my ($self, $mode) = @_;
|
||||
|
||||
if ($self->{select} eq $mode) {
|
||||
$self->{select} = '';
|
||||
} else {
|
||||
if (not $self->{select}) {
|
||||
($self->{ar}, $self->{ac}) = $self->screen_cur();
|
||||
}
|
||||
$self->{select} = $mode;
|
||||
}
|
||||
|
||||
status_area($self);
|
||||
$self->want_refresh();
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
|
||||
sub calc_span {
|
||||
my ($self) = @_;
|
||||
my ($cr, $cc) = $self->screen_cur();
|
||||
my ($br, $bc, $er, $ec);
|
||||
|
||||
if ($self->{select} eq 'b') {
|
||||
$br = $self->line($cr)->beg;
|
||||
$bc = $self->line($cr)->offset_of($cr, $cc);
|
||||
$er = $self->line($self->{ar})->beg;
|
||||
$ec = $self->line($self->{ar})->offset_of($self->{ar}, $self->{ac});
|
||||
($br, $er) = ($er, $br) if $br > $er;
|
||||
($bc, $ec) = ($ec, $bc) if $bc > $ec;
|
||||
} else {
|
||||
if ($cr < $self->{ar}) {
|
||||
($br, $bc, $er, $ec) = ($cr, $cc, $self->{ar}, $self->{ac});
|
||||
} elsif ($cr > $self->{ar}) {
|
||||
($br, $bc, $er, $ec) = ($self->{ar}, $self->{ac}, $cr, $cc);
|
||||
} else {
|
||||
($br, $er) = ($cr, $cr);
|
||||
($bc, $ec) = $cc < $self->{ac} ? ($cc, $self->{ac}) : ($self->{ac}, $cc);
|
||||
}
|
||||
}
|
||||
|
||||
if ($self->{select} eq 'l') {
|
||||
($br, $er) = ($self->line($br)->beg, $self->line($er)->end);
|
||||
($bc, $ec) = (0, $self->ncol);
|
||||
} else {
|
||||
++$ec;
|
||||
}
|
||||
|
||||
return ($br, $bc, $er, $ec);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#/usr/bin/env perl -w
|
||||
|
||||
# Modo de uso: Pon la siguiente línea en tu fichero .Xresources/.Xdefaults
|
||||
# URxvt.perl-ext-common :selection-to-clipboard,pasta
|
||||
# URxvt.keysym.Control-Shift-V :perl:pasta:paste
|
||||
|
||||
use strict;
|
||||
|
||||
sub on_user_command {
|
||||
my ($self, $cmd) = @_;
|
||||
if ($cmd eq "pasta:paste") {
|
||||
$self->selection_request (urxvt::CurrentTime, 3);
|
||||
}
|
||||
()
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
#!/bin/sh
|
||||
# v1.0
|
||||
#Script escrito en POSIX para realizar capturas de pantalla
|
||||
|
||||
# Dependencias: scrot, xclip, herbe
|
||||
|
||||
ayuda(){
|
||||
|
@ -9,9 +7,7 @@ cat << EOF
|
|||
ss_void.sh v1.0 (4/10/2020)
|
||||
Modo de uso:
|
||||
|
||||
ss_void.sh [-PSgsh]
|
||||
|
||||
Script minimalista escrito en POSIX con cuatro opciones para realizar capturas de pantalla.
|
||||
ss_void [-PSgsh]
|
||||
|
||||
Opciones:
|
||||
-P: Guardar captura de pantalla en portapapeles
|
||||
|
@ -34,7 +30,7 @@ do
|
|||
-S)
|
||||
# Guardar captura de pantalla de área seleccionada en el portapapeles
|
||||
sleep 1
|
||||
scrot -s /tmp/'%F_%T.png' -e 'xclip -selection c -t image/png < $f'
|
||||
scrot --line style=dash,width=1,color="red" -s /tmp/'%F_%T.png' -e 'xclip -selection c -t image/png < $f'
|
||||
break
|
||||
;;
|
||||
-g)
|
||||
|
@ -43,14 +39,14 @@ do
|
|||
sleep 1
|
||||
|
||||
# Notificación
|
||||
~/Datos/Git/scripts/varios/dunst_sound.sh
|
||||
$HOME/.local/bin/dunst_sound
|
||||
herbe "CAPTURA DE PANTALLA" "Guardando en: ~/Datos/Capturas"
|
||||
break
|
||||
;;
|
||||
-s)
|
||||
# Guardar captura de pantalla de área seleccionada
|
||||
sleep 1
|
||||
scrot -s -q 50 'Select_%F_%H%M%S_$wx$h.png' -e 'mv $f /home/skynet/Datos/Capturas/select'
|
||||
scrot --line style=dash,width=1,color="red" -s -q 50 'Select_%F_%H%M%S_$wx$h.png' -e 'mv $f /home/skynet/Datos/Capturas/select'
|
||||
|
||||
# Notificación
|
||||
~/Datos/Git/scripts/varios/dunst_sound.sh
|
||||
|
@ -62,12 +58,12 @@ do
|
|||
break
|
||||
;;
|
||||
*)
|
||||
printf '%b' "\033[31;5mOpción inválida\033[0m\n"
|
||||
printf '%b' "\033[37;2mOpciones disponibles:\033[0m\n"
|
||||
printf '%b' "\033[32;1m-P: \033[36;2mGuardar captura de pantalla en portapapeles\033[0m\\033[0m\n"
|
||||
printf '%b' "\033[32;1m-S: \033[36;2mGuardar captura de pantalla del área seleccionada en el portapapeles\033[0m\\033[0m\n"
|
||||
printf '%b' "\033[32;1m-g: \033[36;2mGuardar captura de pantalla en disco duro\033[0m\\033[0m\n"
|
||||
printf '%b' "\033[32;1m-s: \033[36;2mGuardar captura de pantalla de área seleccionada en disco duro\033[0m\\033[0m\n\n"
|
||||
printf "\033[31;5mOpción inválida\033[0m\n\n"
|
||||
printf "\033[37;2m Opciones disponibles:\033[0m\n"
|
||||
printf "\033[32;1m -P: \033[36;2mGuardar captura de pantalla en portapapeles\033[0m\\033[0m\n"
|
||||
printf "\033[32;1m -S: \033[36;2mGuardar captura de pantalla del área seleccionada en el portapapeles\033[0m\\033[0m\n"
|
||||
printf "\033[32;1m -g: \033[36;2mGuardar captura de pantalla en disco duro\033[0m\\033[0m\n"
|
||||
printf "\033[32;1m -s: \033[36;2mGuardar captura de pantalla de área seleccionada en disco duro\033[0m\\033[0m\n\n"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -10,7 +10,7 @@ VOL() {
|
|||
a=$(amixer sget Master | tail -n1 | sed -r "s/.*\[(.*)\]/\1/")
|
||||
b=$(amixer get Master | tail -n1 | sed -r "s/.*\[(.*)%\].*/\1/")
|
||||
|
||||
if [ $a = 'on' ]; then
|
||||
if [ "$a" = 'on' ]; then
|
||||
printf " $b%%"
|
||||
else
|
||||
printf "";
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
case $1 in
|
||||
--toggle)
|
||||
if [ "$(pgrep dropbox)" ]; then
|
||||
herbe "Cerrando Dropbox"
|
||||
pkill -f dropbox &
|
||||
herbe "Dropbox ha sido apagado"
|
||||
else
|
||||
glibc dropbox &
|
||||
herbe "Abriendo Dropbox"
|
||||
|
|
|
@ -32,8 +32,8 @@ do
|
|||
;;
|
||||
-u)
|
||||
# Desmontar dispositivo
|
||||
devmon --unmount "/media/$USER/*" && sleep 2; herbe "DISPOSITIVO USB" "Puede retirarlo con seguridad"
|
||||
pkill -9 devmon && pkill -9 udevil
|
||||
devmon --unmount /media/"$USER"/* && pkill -9 udevil
|
||||
sleep 2; herbe "DISPOSITIVO USB" "Puede retirarlo con seguridad"
|
||||
break
|
||||
;;
|
||||
-U)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Buscar formatos compatibles *.gif *.jpeg *.jpg *.png
|
||||
ls | xargs sxiv -ia "$@" 2>/dev/null
|
||||
sxiv -pa "$@" 2>/dev/null
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
a=$(amixer sget Master | tail -n1 | sed -r "s/.*\[(.*)\]/\1/")
|
||||
b=$(amixer get Master | tail -n1 | sed -r "s/.*\[(.*)%\].*/\1/")
|
||||
|
||||
if [ $a = 'on' ]; then
|
||||
if [ "$a" = 'on' ]; then
|
||||
printf " $b%%"
|
||||
else
|
||||
printf "";
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#!/bin/sh
|
||||
# Alternar estado de conexión wifi
|
||||
# Mac fc:01:7c:9a:bb:d9 corresponde a la tarjeta interna
|
||||
# Mac 50:3e:aa:2c:70:d0 corresponde a la tarjeta externa
|
||||
|
||||
read -r state < /sys/class/net/wlan0/operstate
|
||||
|
||||
|
@ -10,8 +12,8 @@ case "$1" in
|
|||
herbe "Wifi desactivado"
|
||||
else
|
||||
if [ "$state" = "down" ]; then
|
||||
doas wpa_supplicant -B -D wext -c /etc/wpa_supplicant/wpa_supplicant-wlan0.conf -i wlan0
|
||||
# sleep 2; herbe "Wifi activado"
|
||||
doas wpa_supplicant -B -D wext -c /etc/wpa_supplicant/wpa_supplicant-wlan0.conf -i wlan1
|
||||
sleep 2; herbe "Activando wifi..."
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
|
|
@ -15,7 +15,7 @@ fi
|
|||
if [ ! -f "$HOME/void-packages/xbps-src" ]; then
|
||||
printf "No se encontró repositorio git de Void Linux. Clonadolo..."
|
||||
git -C "$HOME" clone --depth=1 https://github.com/void-linux/void-packages.git
|
||||
cd void-packages || return
|
||||
cd void-packages || exit
|
||||
./xbps-src binary-bootstrap
|
||||
echo XBPS_ALLOW_RESTRICTED=yes >> etc/conf
|
||||
fi
|
||||
|
@ -29,7 +29,7 @@ else
|
|||
touch /tmp/upstream_releases
|
||||
fi
|
||||
|
||||
cd "$HOME"/void-packages || return
|
||||
cd "$HOME"/void-packages || exit
|
||||
for i in $(xpkg -L); do
|
||||
./xbps-src update-check "$i" | tee -a /tmp/upstream_releases
|
||||
done
|
||||
|
|
Loading…
Reference in New Issue